首頁 > 軟體

Android 廣播接收器BroadcastReceiver詳解

2022-07-20 18:02:18

一、什麼是BroadcastReceiver

BroadcastReceiver 是安卓系統中四大元件之一,在Android開發中,BroadcastReceiver的應用場景非常多,Android 廣播分為兩個角色:廣播傳送者、廣播接收者。

1.1、作用

廣播接收器用於響應來自其他應用程式或者系統的廣播訊息。

  • 不同元件之間通訊(包括應用內 / 不同應用之間)
  • 與 Android 系統在特定情況下的通訊(如當電話呼入時、網路可用時)
  • 多執行緒通訊

1.2、實現原理

Android中的廣播使用了設計模式中的觀察者模式:基於訊息的釋出/訂閱事件模型。

模型中有3個角色:

  • 訊息訂閱者(廣播接收者)
  • 訊息釋出者(廣播發布者)
  • 訊息中心(AMS,即Activity Manager Service)

廣播接收者通過 Binder機制在AMS註冊

廣播傳送者通過 Binder 機制向AMS傳送廣播

AMS根據廣播傳送者要求,在已註冊列表中,尋找合適的廣播接收者(尋找依據:IntentFilter / Permission)

AMS將廣播傳送到合適的廣播接收者相應的訊息迴圈佇列中;

廣播接收者通過訊息迴圈拿到此廣播,並回撥 onReceive()

二、建立廣播接收器

廣播接收器需要實現為BroadcastReceiver類的子類,並重寫onReceive()方法來接收以Intent物件為引數的訊息。

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("我是建立好的通知");
    }
}

三、註冊廣播接收器

廣播接收器的註冊分為兩種:

  • 靜態註冊
  • 動態註冊

3.1、靜態註冊

應用程式通過在AndroidManifest.xml中註冊廣播接收器來監聽制定的廣播意圖。

註冊

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".MyReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.tiger_test"
            tools:ignore="BatteryLife" />
    </intent-filter>
</receiver>

傳送通知

在Activity 中新增一個傳送通知的點選事件

    public void onClickStatic(View view) {
        System.out.println("MainActivity2.onClickStatic");
//        com.tiger_test 必須和清單檔案中註冊的保持一致
        Intent intent = new Intent();
        intent.setAction("com.tiger_test");
        intent.setPackage("com.traveleasy.activitydemo");
        sendBroadcast(intent);
    }

當點選通知傳送按鈕時,系統會自動範例化MyReceiver類,並註冊到系統中。

靜態註冊是常駐廣播,不受任何元件生命週期的影響

注意:由於自8.0以後隱式廣播不能進行靜態註冊了,所以這裡通過setPackage()指定應用程式響應廣播。

3.2、動態註冊

通過registerReceiver()註冊廣播監聽

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
//        在onCreate 中註冊廣播
        MyReceiver myReceiver = new MyReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.tiger_test");
        registerReceiver(myReceiver, filter);
    }

觸發通知

public void onClickStatic(View view) {
    //        com.tiger_test 必須和註冊的保持一致
    Intent intent = new Intent();
    intent.setAction("com.tiger_test");
    sendBroadcast(intent);
}

在頁面關閉時記得通過unregisterReceiver()登出廣播監聽,否則會因廣播持有Activity參照導致記憶體洩露。

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(myReceiver);
}

執行結果

需要注意,在onReceive()不能執行耗時操作,onReceive()預設是在主執行緒中,進行耗時會阻塞主執行緒,如果非要執行耗時操作最好開啟一個服務在服務中進行耗時操作,不建議開啟執行緒來處理耗時操作,因為BroadCastReceiver的生命週期很短,可能在子執行緒結束前BroadCastReceiver已經退出,如果當BroadCastReceiver所在的程序結束,雖然該程序中可能有使用者啟動的新執行緒,但是由於該程序內沒有活動的元件,系統會在記憶體緊張的時候,優先結束掉該程序,這就會導致BroadCastReceiver啟動的子執行緒不能執行完。

四、系統廣播

上面我們一起學習了自定義廣播,下面我們一起來看一下Android 系統主要的系統廣播型別。

事件常數描述
android.intent.action.BATTERY_CHANGED持久的廣播,包含電池的充電狀態,級別和其他資訊。
android.intent.action.BATTERY_LOW標識裝置的低電量條件。
android.intent.action.BATTERY_OKAY標識電池在電量低之後,現在已經好了。
android.intent.action.BOOT_COMPLETED在系統完成啟動後廣播一次。
android.intent.action.BUG_REPORT顯示報告bug的活動。
android.intent.action.CALL執行呼叫資料指定的某人。
android.intent.action.CALL_BUTTON使用者點選"呼叫"按鈕開啟撥號器或者其他撥號的合適介面。
android.intent.action.DATE_CHANGED日期發生改變。
android.intent.action.REBOOT裝置重啟。

總結

在BroadcastReceiver 中,廣播的型別主要分為兩大類

  • 標註廣播
  • 有序廣播

標準廣播

標準廣播是一種完全非同步執行的廣播,在廣播發出之後,所有的BroadcastReceiver幾乎在同一時刻收到這個廣播訊息,它們之間沒有先後順序,這種廣播的效率較高,並且不能被攔截。

有序廣播

有序廣播是一種完全同步的廣播,在廣播發出後只能有一個BroadcastReceiver能接收到這個廣播訊息,當這個BroadcastReceiver中的邏輯執行完畢後,廣播才能繼續向下傳遞。所以這個廣播是有順序的,所以這種廣播也是可以被攔截的,如果被攔截了後面的BroadCastReceiver則不能收到廣播訊息了。

到此這篇關於Android 廣播接收器BroadcastReceiver詳解的文章就介紹到這了,更多相關Android BroadcastReceiver內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com