Android廣播機制

廣播類型
Android中,廣播主要分爲兩種類型:標準廣播和有序廣播,

  1. 標準廣播是一種完全一步執行的廣播,在廣播發出之後,所有的廣播接收器幾乎都會在同一時刻接收到這條廣播消息,因此他們之間沒有任何先後順序可言.這種廣播效率比較高,但是不能被截斷.

  2. 有序廣播是一種同步執行的廣播,在廣播發出之後,同一時刻只有一個廣播接收器能夠收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞,所以優先級高的廣播接收器可以先收到廣播消息,並且前面的廣播接受器可以截斷正在傳遞的廣播,後面的廣播接收器就無法收到廣播信息了.

    註冊廣播接收器
    廣播接收器的註冊分爲兩種,動態註冊和靜態註冊:
    動態註冊就是在代碼中進行註冊,靜態註冊就是在AndroidManifest.xml中註冊

動態註冊方法:新建一個類,繼承自BroadcastReceiver,並重寫父類的onReceive()方法,當有廣播進來時,onReceive()方法就會得到執行,具體的邏輯就在這個方法中處理.

動態註冊示例:

public class MainActivity extends Activity {
    private NetworkChangeReceiver networkChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver, intentFilter); //註冊廣播接收
        Button button = (Button) findViewById(R.id.sendBroadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("org.superzhao.broadcast.mybroadcast");
                sendBroadcast(intent);//標準廣播
                //sendOrderedBroadcast(intent,null);//有序廣播
            }
        });



    @Override
    protected void onDestroy() { // 註冊了廣播接收,要記得銷燬
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
        localBroadcastManager.unregisterReceiver(localBroadcastReceive);
    }

    //接收是否有網絡的廣播內置類
    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            //Toast.makeText(context,"network changed",Toast.LENGTH_SHORT).show();
            ConnectivityManager connectivityManage =
                    (ConnectivityManager) getSystemService(context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManage.getActiveNetworkInfo();
            if(networkInfo!=null && networkInfo.isAvailable()){
                Toast.makeText(context,"network available",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"network unavailable",Toast.LENGTH_SHORT).show();
            }
        }
    }

一定要記得動態註冊的廣播接收器一定要取消註冊才行.onDestroy()中的代碼就是取消註冊的.

如果程序需要訪問一些系統的關鍵性信息,必須在配置文件中聲明權限纔可以,否則程序將直接崩潰,這是Android中爲了保證應用程序的安全性做的規定

在AndroidManifest.xml文件中添加<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>,代表允許應用程序擁有查看網絡狀態的權限

靜態註冊方法:

同樣新建一個廣播接收器類,然後在AndroidManifest.xml文件中添加

<receiver android:name=".MyBroadcast" >
            <intent-filter android:priority="50">
                <action android:name="org.superzhao.broadcast.mybroadcast">

                </action>
            </intent-filter>
        </receiver>

在 中通過android:name指定具體註冊哪一個廣播接收器,在 中指定要接收的廣播的名稱,

發送有序廣播
發送有序廣播就是像上面第一個代碼那樣,只不過sendBroadcast(intent)變成了sendOrderedBroadcast(intent,null)就可以發送有序廣播了,有序廣播中可以在 中使用android:priority=”50”設置接收廣播的順序,裏面的數字越大優先級越高,有序廣播也可以讓先接收到廣播的接收器截斷廣播,使它不向下傳遞,在優先接收的接收器的onReceive()方法中加入abortBroadcast() 這句代碼就可以截斷廣播了.

使用本地廣播
上面說的廣播都是屬於系統全局廣播,也就是發出的廣播可以被其他任何應用程序接收到,這樣就容易引起安全性的問題,爲了解決這個問題,Android引入了一套本地廣播機制,使用這個機制發出的廣播只能夠在應用程序的內部進行傳遞,並且廣播接收器也只能接收來自本應用程序發出的廣播,這樣安全心的問題就都不存在了.
本地廣播示例:

public class MainActivity extends Activity {
    private LocalBroadcastManager localBroadcastManager;
    private LocalBroadcastReceive localBroadcastReceive;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //發送本地廣播
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        localBroadcastReceive = new LocalBroadcastReceive();
        Button button1 = (Button)findViewById(R.id.sendLocalBroadcast);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("org.superzhao.broadcast.myLocalBroadcast");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
        localBroadcastManager.registerReceiver(localBroadcastReceive,intentFilter1);
    }

    @Override
    protected void onDestroy() { // 註冊了廣播接收,要記得銷燬
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localBroadcastReceive);
    }


    //本地廣播接收類
    class LocalBroadcastReceive extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"localbroadcast receive",Toast.LENGTH_SHORT).show();
        }
    }

}

本地廣播是無法通過靜態註冊的方式來接收的,其實這也完全可以理解,因爲靜態註冊主要就是爲了讓程序在未啓動的情況在也能接收到廣播,而發送本地廣播時,程序肯定已經啓動了,因此不需要使用靜態註冊的功能.

總結本地廣播的優勢:

  1. 可明確知道正在發送的廣播不會離開我們的程序,因此不需要擔心機密數據泄漏的問題.
  2. 其他的程序無法將廣播發送到我們程序的內部,因此不需要擔心有安全漏洞的隱患.
  3. 發送本地廣播比起發送系統廣播將更加高效
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章