Android?廣播接收器BroadcastReceiver詳解
一、什么是BroadcastReceiver
BroadcastReceiver 是安卓系統(tǒng)中四大組件之一,在Android開發(fā)中,BroadcastReceiver的應(yīng)用場景非常多,Android 廣播分為兩個角色:廣播發(fā)送者、廣播接收者。
1.1、作用
廣播接收器用于響應(yīng)來自其他應(yīng)用程序或者系統(tǒng)的廣播消息。
- 不同組件之間通信(包括應(yīng)用內(nèi) / 不同應(yīng)用之間)
- 與 Android 系統(tǒng)在特定情況下的通信(如當(dāng)電話呼入時、網(wǎng)絡(luò)可用時)
- 多線程通信
1.2、實(shí)現(xiàn)原理
Android中的廣播使用了設(shè)計(jì)模式中的觀察者模式:基于消息的發(fā)布/訂閱事件模型。
模型中有3個角色:
- 消息訂閱者(廣播接收者)
- 消息發(fā)布者(廣播發(fā)布者)
- 消息中心(AMS,即Activity Manager Service)
廣播接收者通過 Binder機(jī)制在AMS注冊
廣播發(fā)送者通過 Binder 機(jī)制向AMS發(fā)送廣播
AMS根據(jù)廣播發(fā)送者要求,在已注冊列表中,尋找合適的廣播接收者(尋找依據(jù):IntentFilter / Permission)
AMS將廣播發(fā)送到合適的廣播接收者相應(yīng)的消息循環(huán)隊(duì)列中;
廣播接收者通過消息循環(huán)拿到此廣播,并回調(diào) onReceive()
二、創(chuàng)建廣播接收器
廣播接收器需要實(shí)現(xiàn)為BroadcastReceiver類的子類,并重寫onReceive()方法來接收以Intent對象為參數(shù)的消息。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("我是創(chuàng)建好的通知");
}
}三、注冊廣播接收器
廣播接收器的注冊分為兩種:
- 靜態(tài)注冊
- 動態(tài)注冊
3.1、靜態(tài)注冊
應(yīng)用程序通過在AndroidManifest.xml中注冊廣播接收器來監(jiān)聽制定的廣播意圖。

注冊
<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>發(fā)送通知
在Activity 中新增一個發(fā)送通知的點(diǎn)擊事件
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);
}當(dāng)點(diǎn)擊通知發(fā)送按鈕時,系統(tǒng)會自動實(shí)例化MyReceiver類,并注冊到系統(tǒng)中。

靜態(tài)注冊是常駐廣播,不受任何組件生命周期的影響
注意:由于自8.0以后隱式廣播不能進(jìn)行靜態(tài)注冊了,所以這里通過setPackage()指定應(yīng)用程序響應(yīng)廣播。
3.2、動態(tài)注冊
通過registerReceiver()注冊廣播監(jiān)聽
@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);
}觸發(fā)通知
public void onClickStatic(View view) {
// com.tiger_test 必須和注冊的保持一致
Intent intent = new Intent();
intent.setAction("com.tiger_test");
sendBroadcast(intent);
}
在頁面關(guān)閉時記得通過unregisterReceiver()注銷廣播監(jiān)聽,否則會因廣播持有Activity引用導(dǎo)致內(nèi)存泄露。
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
運(yùn)行結(jié)果

需要注意,在onReceive()不能執(zhí)行耗時操作,onReceive()默認(rèn)是在主線程中,進(jìn)行耗時會阻塞主線程,如果非要執(zhí)行耗時操作最好開啟一個服務(wù)在服務(wù)中進(jìn)行耗時操作,不建議開啟線程來處理耗時操作,因?yàn)锽roadCastReceiver的生命周期很短,可能在子線程結(jié)束前BroadCastReceiver已經(jīng)退出,如果當(dāng)BroadCastReceiver所在的進(jìn)程結(jié)束,雖然該進(jìn)程中可能有用戶啟動的新線程,但是由于該進(jìn)程內(nèi)沒有活動的組件,系統(tǒng)會在內(nèi)存緊張的時候,優(yōu)先結(jié)束掉該進(jìn)程,這就會導(dǎo)致BroadCastReceiver啟動的子線程不能執(zhí)行完。
四、系統(tǒng)廣播
上面我們一起學(xué)習(xí)了自定義廣播,下面我們一起來看一下Android 系統(tǒng)主要的系統(tǒng)廣播類型。
| 事件常量 | 描述 |
|---|---|
| android.intent.action.BATTERY_CHANGED | 持久的廣播,包含電池的充電狀態(tài),級別和其他信息。 |
| android.intent.action.BATTERY_LOW | 標(biāo)識設(shè)備的低電量條件。 |
| android.intent.action.BATTERY_OKAY | 標(biāo)識電池在電量低之后,現(xiàn)在已經(jīng)好了。 |
| android.intent.action.BOOT_COMPLETED | 在系統(tǒng)完成啟動后廣播一次。 |
| android.intent.action.BUG_REPORT | 顯示報(bào)告bug的活動。 |
| android.intent.action.CALL | 執(zhí)行呼叫數(shù)據(jù)指定的某人。 |
| android.intent.action.CALL_BUTTON | 用戶點(diǎn)擊"呼叫"按鈕打開撥號器或者其他撥號的合適界面。 |
| android.intent.action.DATE_CHANGED | 日期發(fā)生改變。 |
| android.intent.action.REBOOT | 設(shè)備重啟。 |
總結(jié)
在BroadcastReceiver 中,廣播的類型主要分為兩大類
- 標(biāo)注廣播
- 有序廣播
標(biāo)準(zhǔn)廣播
標(biāo)準(zhǔn)廣播是一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,所有的BroadcastReceiver幾乎在同一時刻收到這個廣播消息,它們之間沒有先后順序,這種廣播的效率較高,并且不能被攔截。
有序廣播
有序廣播是一種完全同步的廣播,在廣播發(fā)出后只能有一個BroadcastReceiver能接收到這個廣播消息,當(dāng)這個BroadcastReceiver中的邏輯執(zhí)行完畢后,廣播才能繼續(xù)向下傳遞。所以這個廣播是有順序的,所以這種廣播也是可以被攔截的,如果被攔截了后面的BroadCastReceiver則不能收到廣播消息了。
到此這篇關(guān)于Android 廣播接收器BroadcastReceiver詳解的文章就介紹到這了,更多相關(guān)Android BroadcastReceiver內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
揭秘雙十一手機(jī)淘寶圖標(biāo)如何被動態(tài)更換
這篇文章主要介紹了每到雙十一十二的時候Android手機(jī)動態(tài)更換手機(jī)圖標(biāo)的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08
PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載
這篇文章主要介紹了PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載的相關(guān)資料,需要的朋友可以參考下2015-10-10
Android實(shí)現(xiàn)訂單倒計(jì)時功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)訂單倒計(jì)時的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01
代碼從windows下visual studio到andriod平臺遷移實(shí)現(xiàn)步驟
這篇文章主要介紹了代碼從windows下visual studio到andriod平臺遷移的修改記錄的相關(guān)資料,需要的朋友可以參考下2017-01-01
Android實(shí)現(xiàn)圖片瀏覽并改變透明度
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片瀏覽并改變透明度,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-08-08
Android編程實(shí)現(xiàn)兩個Activity相互切換而不使用onCreate()的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)兩個Activity相互切換而不使用onCreate()的方法,結(jié)合實(shí)例形式分析了多個Activity切換而不重新創(chuàng)建的操作技巧,需要的朋友可以參考下2017-01-01

