Broadcast(廣播) 是 Android 的四大組件之一,用於進程/線程間通訊。java
廣播最大的特色就是發送方並不關心接收方是否接到數據,也不關心接收方是如何處理數據的,它只負責「說」而無論你「聽不聽」。android
廣播能夠來之系統,例如,Android 系統在發生各類系統事件時發送廣播(系統啓動或者設備開始充電時)。git
也能夠來自於其餘應用程序,例如,應用程序也能夠發送自定義廣播,來通知其餘應用程序接受他們可能感興趣的內容(更新數據)。github
是一種「徹底異步執行」的廣播,沒有任何前後順序,全部的廣播接收器幾乎同一時刻接收到這條廣播消息,效率高,沒法被截斷。安全
是一種「同步執行」的廣播,有前後順序,同一時刻只有一個接收器能夠接收這個廣播消息,優先級高的廣播接收器能夠先收到廣播消息,而且前面的廣播接收器還能夠截斷正在傳遞的廣播,這樣後面的廣播接收器就沒法接收廣播消息了。網絡
無論應用程序是否處於活動狀態,都會進行監聽。每次觸發都會創建新的 Receiver 對象。app
在代碼中進行註冊,注意動態註冊的廣播必定要取消註冊才行,一般是在 onDestroy()
方法中調用 unregisterReceiver()
方法來實現。異步
從開始建立直到其被解除註冊會使用同一個 Receiver,不管這個廣播被觸發幾回。ide
Android 系統中內置了多個系統廣播,每一個系統廣播都具備特定的 IntentFilter,其中主要包括具體的 Action,系統廣播發出後,將被相應的 BroadcastReceiver 接收。系統廣播在系統內部當特定事件發生時,由系統自動發出。學習
由應用程序開發者本身定義的廣播。
發出的廣播能夠被其餘任意的應用程序接收,或者能夠接收來自其餘任意應用程序的廣播。
只能在應用程序的內部進行傳遞的廣播,廣播接收器也只能接收內部的廣播,不能接受其餘應用程序的廣播。
使用廣播咱們須要先建立 BroadcastReceiver(廣播接收器) ,直接繼承 BroadcastReceiver 建立子類並實現父類的 onReceive()
方法便可,以下示例代碼。
public class MyReceiver extends BroadcastReceiver {
// 自定義 action
private static final String ACTION = "com.jeanboy.broadcast.MyReceiverFilter";
@Override
public void onReceive(Context context, Intent intent) {
//TODO: 接收到廣播進行處理
}
}
複製代碼
在使用廣播時還須要在 AndroidMainfest 文件中定義,也就是註冊靜態廣播。
<receiver android:name=".ui.broadcast.MyReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<!-- 例如:接收系統開機廣播 -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
<!-- 例如:接收自定義的廣播 -->
<action android:name="com.jeanboy.broadcast.MyReceiverFilter" />
</intent-filter>
</receiver>
複製代碼
上面的 enabled 設置爲 true 意味着可以接受到廣播信息。exported 爲 true 意味着可以接收到外部 APK 發送的廣播信息。
使用動態廣播不須要在 AndroidMainfest 文件中定義,只需在代碼中註冊便可。
// 建立廣播
MyReceiver myReceiver = new MyReceiver();
// 建立 IntentFilter
IntentFilter intentFilter = new IntentFilter();
// 例如:添加系統廣播 action 接受網絡變化
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
// 例如:添加自定義的 action
intentFilter.addAction(MyReceiver.ACTION);
// 註冊廣播
registerReceiver(myReceiver, intentFilter);
// 註銷廣播
unregisterReceiver(myReceiver);
複製代碼
發送廣播比較簡單,不管靜態廣播仍是動態廣播,都是以下方式(系統廣播 Android 系統會自動發送,不在本文討論範圍)。
// 建立 Intent
Intent intent = new Intent();
// 例如:添加自定義的 action
intent.setAction(MyReceiver.ACTION);
// 發送廣播
sendBroadcast(intent);
複製代碼
因爲 Android 8.0 廢除大部分靜態廣播,對於代碼須要修改某些部分。
發送廣播部分須要設置 ComponetName
。
Intent intent = new Intent(MyReceiver.ACTION);
// ComponetName("自定義廣播的包名", "自定義廣播的路徑")
ComponentName component = new ComponentName("com.jeanboy.app.broadcast", "com.jeanboy.app.broadcast.MyReceiver");
intent.setComponent(component);
sendBroadcast(intent);
複製代碼
使用廣播可能引起的安全問題:
爲了不以上安全問題,Android 爲咱們提供了權限機制。
首先在註冊靜態廣播時能夠在 AndroidMainfest 文件中添加權限。
<manifest ...>
<!-- 自定義一個本身的權限 -->
<permission android:name="com.jeanboy.permissions.MY_BROADCAST"/>
<!-- 使用自定義的權限 -->
<uses-permission android:name="com.jeanboy.permissions.MY_BROADCAST"/>
<application ...>
<!-- 添加權限 -->
<receiver android:name=".ui.broadcast.MyReceiver" android:permission="com.jeanboy.broadcast.MY_BROADCAST" android:enabled="true" android:exported="true">
<intent-filter>
<!-- 例如:接收自定義的廣播 -->
<action android:name="com.jeanboy.broadcast.MyReceiverFilter" />
</intent-filter>
</receiver>
</application>
</manifest>
複製代碼
而後在咱們發送廣播時,能夠爲它指定一個權限,只有具備該權限的應用才能接收到廣播,以下所示:
// 建立 Intent
Intent intent = new Intent();
// 例如:添加自定義的 action
intent.setAction(MyReceiver.ACTION);
// 發送廣播,添加權限
sendBroadcast(intent, "com.jeanboy.permissions.MY_BROADCAST");
複製代碼
上面介紹的 BroadcastReceiver 用於應用之間的傳遞消息,本質上它是跨進程的,還有可能被其餘應用攔截。
而 LocalBroadcast(本地廣播)用於應用內部傳遞消息,比 BroadcastReceiver 更加高效,它只在應用內部有效,不須要考慮安全問題。
本地廣播的建立仍然是繼承 BroadcastReceiver 建立子類,並實現父類的 onReceive()
方法。在註冊、發送、註銷廣播時使用 LocalBroadcastManager 來進行相關操做。
// 建立廣播
MyReceiver myReceiver = new MyReceiver();
// 建立 IntentFilter
IntentFilter intentFilter = new IntentFilter();
// 例如:添加自定義的 action
intentFilter.addAction(MyReceiver.ACTION);
// 註冊本地廣播
LocalBroadcastManager.getInstance(this)
.registerReceiver(myReceiver, intentFilter);
// 發送廣播
Intent intent = new Intent(MyReceiver.ACTION));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
// 註銷本地廣播
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
複製代碼
歡迎關注個人公衆號,分享各類技術乾貨,各類學習資料,職業發展和行業動態。
歡迎加入技術交流羣,來一塊兒交流學習。