BroadcastReciver 詳解


BroadcastReciver 位於 android.content 包下,主要用於對廣播消息(Intent)的過濾並響應的控件。可以理解爲全局的監聽器。BroadcastReceiver 自身並不實現圖形用戶界面,但是當它收到某個廣播消息後,BroadcastReceiver 可以啓動 Activity 作爲響應,或者啓動 Service 服務等等。

目錄

-廣播分類

-靜態廣播

-動態廣播

-廣播發送

-廣播接收器

-8.0 靜態廣播

-帶權限的廣播

-本地廣播

廣播分類

Broadcast(廣播)是Android的四大組件之一,用於進程/線程間通信。按照不同的方式分類有不同的歸類

######發送方式

1.標準廣播

完全異步執行的廣播,沒有先後順序,不可被攔截,效率高

2.有序廣播

同步執行的廣播,有先後順序,發送出去的廣播被廣播接收者按照先後順序接收,並且前面的廣播接收器還可以截斷正在傳遞的廣播,這樣後面的廣播接收器就無法接收廣播消息了。

######註冊方式

1.靜態廣播

不管應用程序是否處於活動狀態,都會進行監聽。每次觸發都會建立新的 Receiver 對象。

2.動態廣播

代碼中進行註冊,動態註冊的廣播一定要取消註冊才行,通常是在 onDestroy()方法中調用 unregisterReceiver()方法來實現。從開始創建直到其被解除註冊會使用同一個 Receiver,無論這個廣播被觸發幾次。

######定義方式

1.系統廣播

Android 系統中內置了多個系統廣播,每個系統廣播都具有特定的 IntentFilter,其中主要包括具體的 Action,系統廣播發出後,將被相應的 BroadcastReceiver 接收。系統廣播在系統內部當特定事件發生時,由系統自動發出。

2.自定義廣播

開發者自己定義的廣播

######範圍方式

1.全局廣播

發出的廣播可以被其他任意的應用程序接收,或者可以接收來自其他任意應用程序的廣播。

2.本地廣播

只能在本應用程序的內部進行傳遞的廣播,廣播接收器也只能接收內部的廣播,不能接受其他應用程序的廣播。

介紹完廣播按照不同方式的不同歸類,接下來來講解一下廣播的使用

靜態廣播

靜態廣播的註冊是在 AndroidMainfest.xml 中定義的

<receiver android:name=".ui.broadcast.MyReceiver"
          android:enabled="true"
          android:exported="true">
    <intent-filter>
        <!-- 接收系統開機廣播 -->
        <action android:name="android.intent.action.ACTION_BATTERY_LOW" />
        <!-- 接收自定義的廣播 -->
        <action android:name="com.madreain.broadcast.MyReceiverFilter" />
    </intent-filter>
</receiver>

enabled="true"代表能夠接受到廣播信息。exported="true"代表能夠接收到外部 APK 發送的廣播信息

動態廣播

動態廣播只需要在使用的代碼中註冊

MyReceiver myReceiver = new MyReceiver();

IntentFilter intentFilter = new IntentFilter();
// 系統廣播 action 接受網絡變化
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
// 自定義的 action
intentFilter.addAction(MyReceiver.ACTION);
registerReceiver(myReceiver, intentFilter);

在onDestory方法中註銷廣播
unregisterReceiver(myReceiver);

廣播發送

無論靜態廣播還是動態廣播,發送廣播的方式都是一樣的

Intent intent = new Intent();
// 自定義的 action
intent.setAction(MyReceiver.ACTION);
sendBroadcast(intent);

廣播接收器

廣播的接受,創建廣播接收器來實現廣播的接受


public class MyReceiver extends BroadcastReceiver {

  private static final String ACTION = "com.madreain.broadcast.MyReceiverFilter";

  @Override
  public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION) ){
              //接收固定廣播進行處理

        }
  }
}

8.0 靜態廣播

Android8.0 引入了新的廣播接收器限制,因此您應該移除所有爲隱式廣播 Intent 註冊的廣播接收器。將它們留在原位並不會在構建時或運行時令應用失效,但當應用運行在 Android8.0 上時它們不起任何作用。顯式廣播 Intent(只有您的應用可以響應的 Intent)在 Android8.0 上仍以相同方式工作。這個新增限制有一些例外情況。如需查看在以 Android 8.0 爲目標平臺的應用中仍然有效的隱式廣播的列表,請參閱隱式廣播例外

8.0 發送廣播需修改,需設置 ComponetName,ComponetName(“自定義廣播的包名”, “自定義廣播的路徑”)

Intent intent = new Intent(STATICACTION);
intent.setComponent(new ComponentName("com.madreain.broadcast", "com.madreain.broadcast.MyReceiver"));
sendBroadcast(intent);

帶權限的廣播

在廣播的實際應用中,我們爲了避免別的應用監聽我們的廣播,或者別人的應用冒充我們的應用進行發送廣播。我們在使用中可以給廣播增加權限來避免這些安全問題

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.madreain">

  <!-- 自定義一個自己的權限 -->
  <permission android:name="com.madreain.permissions.MY_BROADCAST"/>

  <!-- 使用自定義的權限 -->
  <uses-permission android:name="com.madreain.permissions.MY_BROADCAST"/>

  <application ...>

    <!-- 添加權限 -->
    <receiver android:name=".ui.broadcast.MyReceiver"
              android:permission="com.madreain.broadcast.MY_BROADCAST"
              android:enabled="true"
              android:exported="true">
      <intent-filter>
        <!-- 例如:接收自定義的廣播 -->
        <action android:name="com.madreain.broadcast.MyReceiverFilter" />
      </intent-filter>
    </receiver>

  </application>

</manifest>

在發送廣播時,我們也得指定權限,讓具有權限的應用才能接受到此廣播

Intent intent = new Intent();
intent.setAction(MyReceiver.ACTION);
// 發送廣播,添加權限
sendBroadcast(intent, "com.madreain.permissions.MY_BROADCAST");

其實爲了解決 Android 的廣播安全問題,Android 還引入了另一個 LocalBroadcastManger 類,接下來的本地廣播來介紹

本地廣播

本地廣播用於應用內部傳遞消息,比 BroadcastReceiver 更加高效,它只在應用內部有效,不需要考慮安全問題。本地廣播的創建仍然是繼承 BroadcastReceiver 創建子類,並實現父類的 onReceive() 方法。在註冊、發送、註銷廣播時使用 LocalBroadcastManager 來進行相關操作。

發送廣播

Intent intent = new Intent(MyReceiver.ACTION));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

接受廣播

MyReceiver myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MyReceiver.ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);

註銷廣播

LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);

在此推薦一個第三方消息傳遞的庫EventBus,後期文章將把BroadcastReciver和EventBus做對比進行分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章