Android學(xué)習(xí)之四大組件(三)Broadcast Receiver

問題:什么是Broadcast Receiver

先說答案:
廣播接收者(Broadcast Receiver)
是Android 應(yīng)用開發(fā)中的一個核心組件,用于監(jiān)聽和響應(yīng)系統(tǒng)級別或應(yīng)用級別的廣播消息猬膨。
廣播消息是在應(yīng)用程序或Android系統(tǒng)之間傳遞的信息,可以是諸如設(shè)備屏幕關(guān)閉嗤疯、電池電量低蔚润、一段時間后觸發(fā)的提醒、應(yīng)用安裝或卸載等事件的通知。

主要特性:

事件驅(qū)動:廣播接收器被設(shè)計用來響應(yīng)廣播消息词疼,這些消息通常對應(yīng)于系統(tǒng)事件或應(yīng)用內(nèi)事件。

系統(tǒng)廣播:Android系統(tǒng)會發(fā)出多種系統(tǒng)級別的廣播帘腹,例如開機贰盗、網(wǎng)絡(luò)變化、短信到達(dá)等阳欲。

應(yīng)用廣播:應(yīng)用可以發(fā)送自定義廣播舵盈,其他應(yīng)用的廣播接收器可以選擇監(jiān)聽這些廣播陋率。

怎么發(fā)送廣播:
發(fā)送普通廣播:
普通廣播是完全異步的,所有接收器幾乎同時接收到廣播翘贮,它們的執(zhí)行順序不能被指定爆惧。
Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data", "Something interesting");
sendBroadcast(intent);

發(fā)送有序廣播:
有序廣播按照接收器聲明的優(yōu)先級(在 AndroidManifest.xml 中用 android:priority 屬性指定)順序發(fā)送芍耘。
當(dāng)多個接收器監(jiān)聽相同的動作時,系統(tǒng)會根據(jù)優(yōu)先級從高到低依次發(fā)送廣播坝初。
Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data", "Something interesting");
sendOrderedBroadcast(intent, null);

怎么接收廣播:
靜態(tài)注冊
靜態(tài)注冊意味著在應(yīng)用的AndroidManifest.xml文件中聲明廣播接收器。
這樣注冊的接收器可以接收到即使應(yīng)用未運行時發(fā)出的廣播事件拗小。
要靜態(tài)注冊一個廣播接收器哀九,你需要在AndroidManifest.xml文件中添加<receiver>標(biāo)簽,
并且在<intent-filter>標(biāo)簽內(nèi)指定需要監(jiān)聽的廣播動作。
<receiver android:name=".MyBroadcastReceiver" android:exported="true">
? ? <intent-filter>
? ? ? ? <action android:name="com.example.broadcast.MY_NOTIFICATION"/>
? ? ? ? <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
? ? </intent-filter>
</receiver>

動態(tài)注冊動態(tài)注冊是在代碼中進(jìn)行的簿寂,通常是在一個組件(如Activity或Service)的生命周期內(nèi)常遂。
這樣注冊的接收器只有在組件運行時才能接收廣播平绩。
要動態(tài)注冊廣播接收器跃赚,你需要創(chuàng)建IntentFilter纬傲,并調(diào)用registerReceiver()方法。
public class MyActivity extends Activity {
? ? private MyBroadcastReceiver myReceiver;
? ? private IntentFilter intentFilter;
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? // 實例化廣播接收器和意圖過濾器
? ? ? ? myReceiver = new MyBroadcastReceiver();
? ? ? ? intentFilter = new IntentFilter("com.example.broadcast.MY_NOTIFICATION");
? ? ? ? // 注冊廣播接收器
? ? ? ? registerReceiver(myReceiver, intentFilter);
? ? }
? ? @Override
? ? protected void onDestroy() {
? ? ? ? super.onDestroy();
? ? ? ? // 注銷廣播接收器
? ? ? ? unregisterReceiver(myReceiver);
? ? }
}

動態(tài)注冊的廣播接收器不會在應(yīng)用未運行時接收廣播,因此它不會像靜態(tài)注冊的那樣增加應(yīng)用的內(nèi)存使用侠讯。

中止廣播/邏輯處理(靜態(tài)注冊動態(tài)注冊的就是下面這個東西):

僅有序廣播可以被中止,普通廣播不能被中止袁翁。在有序廣播中,當(dāng)前接收到廣播的接收器可以調(diào)用abortBroadcast()方法來中止廣播焙压,這樣優(yōu)先級較低的其他接收器就不會再接收到這個廣播了。
public class MyReceiver extends BroadcastReceiver {
? ? @Override
? ? public void onReceive(Context context, Intent intent) {
? ? ? ? // 判斷是否是需要中止的廣播
? ? ? ? if ("com.example.broadcast.MY_NOTIFICATION".equals(intent.getAction())) {
? ? ? ? ? ? // 邏輯處理
? ? ? ? ? ? // ...
? ? ? ? ? ? // 中止廣播
? ? ? ? ? ? abortBroadcast();
? ? ? ? }
? ? }
}

權(quán)限控制:

在發(fā)送和接收廣播時,可以通過指定權(quán)限來限制哪些應(yīng)用可以接收廣播绰沥。發(fā)送廣播時零截,可以在?sendBroadcast?或?sendOrderedBroadcast?方法中傳遞一個權(quán)限字符串,系統(tǒng)會確保只有擁有這個權(quán)限的接收器才能接收到該廣播。


生命周期和限制:

廣播接收器沒有自己的用戶界面傻铣。
它們的生命周期非常短暫蜕径,只在?onReceive()?方法調(diào)用期間存活梦染。
執(zhí)行長時間運行的操作不應(yīng)該在?onReceive()?方法中直接進(jìn)行,而是應(yīng)該通過啟動一個服務(wù)(如?IntentService)來進(jìn)行朴皆。

注意事項:

性能:廣播接收器的執(zhí)行對性能有影響帕识,因此應(yīng)該避免在onReceive()方法中進(jìn)行重型操作。
權(quán)限:接收某些系統(tǒng)廣播可能需要相應(yīng)的權(quán)限遂铡。
隱式廣播限制:為了提高系統(tǒng)性能肮疗,Android 8.0(API 級別 26)引入了對靜態(tài)注冊的隱式廣播的限制。
線程:onReceive()方法默認(rèn)運行在主線程(UI線程)扒接,因此在此方法中進(jìn)行的任何耗時操作都會阻塞UI線程伪货。

最佳實踐:

考慮隱私和安全性:避免發(fā)送敏感信息,或者確保通過權(quán)限限制其訪問钾怔。

注意性能:不要在?onReceive()?方法中執(zhí)行長時間運行的任務(wù)碱呼。

考慮使用本地廣播:如果廣播僅在自己的應(yīng)用內(nèi)部通信,可以考慮使用?LocalBroadcastManager宗侦。它不是跨應(yīng)用的巍举,因此更安全,也更高效凝垛。不過從AndroidX庫開始懊悯,LocalBroadcastManager?被標(biāo)記為廢棄,推薦使用其他方式梦皮,例如?LiveData?或者?EventBus炭分。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剑肯,隨后出現(xiàn)的幾起案子捧毛,更是在濱河造成了極大的恐慌,老刑警劉巖让网,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呀忧,死亡現(xiàn)場離奇詭異,居然都是意外死亡溃睹,警方通過查閱死者的電腦和手機而账,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來因篇,“玉大人泞辐,你說我怎么就攤上這事【鹤遥” “怎么了咐吼?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長商佑。 經(jīng)常有香客問我锯茄,道長,這世上最難降的妖魔是什么茶没? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任肌幽,我火速辦了婚禮,結(jié)果婚禮上礁叔,老公的妹妹穿的比我還像新娘牍颈。我一直安慰自己,他們只是感情好琅关,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布煮岁。 她就那樣靜靜地躺著,像睡著了一般涣易。 火紅的嫁衣襯著肌膚如雪画机。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天新症,我揣著相機與錄音步氏,去河邊找鬼。 笑死徒爹,一個胖子當(dāng)著我的面吹牛荚醒,可吹牛的內(nèi)容都是我干的芋类。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼界阁,長吁一口氣:“原來是場噩夢啊……” “哼侯繁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起泡躯,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贮竟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后较剃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咕别,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年写穴,在試婚紗的時候發(fā)現(xiàn)自己被綠了惰拱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡确垫,死狀恐怖弓颈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情删掀,我是刑警寧澤翔冀,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站披泪,受9級特大地震影響纤子,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜款票,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一控硼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧艾少,春花似錦卡乾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谍椅,卻和暖如春误堡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雏吭。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工锁施, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓悉抵,卻偏偏與公主長得像肩狂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子基跑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容