Android四大組件之廣播接收器(一)

Android 中的每個應用程序都可以對自己感興趣的廣播進行註冊,這樣該程序就只會接收到自己所關心的廣播內容,這些廣播可能是來自於系統的,也可能是來自於其他應用程序的。

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


標準廣播(Normal broadcasts)是一種完全異步執行的廣播,在廣播發出之後,所有的廣播接收器幾乎都會在同一時刻接收到這條廣播消息,因此它們之間沒有任何先後順序可言。這種廣播的效率會比較高,但同時也意味着它是無法被截斷的。


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



接受系統廣播有兩種方式

動態註冊(在代碼中註冊,以檢測網絡狀態爲例)

代碼示例:

public class MainActivity extends AppCompatActivity {

    //設定廣播的過濾信息
    IntentFilter intentFilter;
    //定義網絡廣播接收器
    NetworkChangeReceiver receiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        //設置過濾
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        receiver = new NetworkChangeReceiver();
        //註冊廣播接收器
        registerReceiver(receiver,intentFilter);
    }

    //在onDestroy方法中註銷廣播接收器
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

    class NetworkChangeReceiver extends BroadcastReceiver{

        //當接收到網絡變動時,自動執行該方法
        @Override
        public void onReceive(Context context, Intent intent) {
            //獲取網絡狀態
            ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

            if(networkInfo!=null&&networkInfo.isAvailable()){
                Toast.makeText(context, "網絡可用", Toast.LENGTH_SHORT).show();
            }
            else{
                Toast.makeText(context, "網絡不可用", Toast.LENGTH_SHORT).show();
            }
        }
    }

}

靜態註冊(在AndroidManifest.xml中註冊,以實現開機啓動爲例

動態註冊的廣播接收器可以自由地控制註冊與註銷,在靈活性方面有很大的優勢,但是它也存在着一個缺點,即必須要在程序啓動之後才能接收到廣播(這必然是在系統啓動之後),因爲註冊的邏輯是寫在onCreate()方法中的,而靜態註冊則可以在開機時啓動。

靜態註冊實現開機啓動程序原理:接收開機時的廣播,收到即啓動程序

新建SystemLaunchReceiver類

public class SystemLaunchReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "在這裏添加系統啓動時你想要做的事", Toast.LENGTH_LONG).show();
    }
}

在AndroidManifest的application中添加註冊信息

<receiver android:name=".SystemLaunchReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

監聽系統開機廣播需要聲明權限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


PS:不要在onReceive()方法中添加過多的邏輯或者進行任何的耗時操作,因爲在廣播接收器中是不允許開啓線程的, 當 onReceive()方法運行了較長時間而沒有結束時, 程序就會報錯。因此廣播接收器更多的是扮演一種打開程序其他組件的角色,比如創建一條狀態欄通知,或者啓動一個服務等。


PS:

關於IntentFilter:

當Intent在組件間傳遞時,組件如果想告知Android系統自己能夠響應和處理哪些Intent,那麼就需要用到IntentFilter對象。 顧名思義,IntentFilter對象負責過濾掉組件無法響應和處理的Intent,只將自己關心的Intent接收進來進行處理。 IntentFilter實行“白名單”管理,即只列出組件樂意接受的Intent,但IntentFilter只會過濾隱式Intent,顯式的Intent會直接傳送到目標組件。 Android組件可以有一個或多個IntentFilter,每個IntentFilter之間相互獨立,只需要其中一個驗證通過則可。除了用於過濾廣播的IntentFilter可以在代碼中創建外,其他的IntentFilter必須在AndroidManifest.xml文件中進行聲明。(在廣播中我們用到了IntentFilter)


關於文中用到的ConnectivityManager可參考:http://blog.csdn.net/oyangyujun/article/details/41723865


以上就是Android廣播的接收機制了,有時間我再補上廣播的發送方法以及其他和廣播有關的內容

發佈了195 篇原創文章 · 獲贊 194 · 訪問量 67萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章