簡(jiǎn)介
BroadcastReceiver(廣播接收器)是Android四大組件之一,顧名思義,通過廣播的方式進(jìn)行消息傳遞,其本質(zhì)是一個(gè)全局的監(jiān)聽器,可以監(jiān)聽到各種廣播,可以用來實(shí)現(xiàn)不同組件之間的通信。廣播最大的特點(diǎn)就是發(fā)送方并不關(guān)心接收方是否接到數(shù)據(jù),也不關(guān)心接收方是如何處理數(shù)據(jù)的,通過這樣的形式來達(dá)到接、收雙方的完全解耦合。
類別
- 普通廣播(Normal Broadcast)
- 有序廣播(Ordered Broadcast)
- 粘性廣播(Sticky Broadcast)
- 系統(tǒng)廣播(System Broadcast)
- 本地廣播(Local Broadcast)
普通廣播(Normal Broadcast)
又稱無序廣播,這種廣播完全是異步的,所有與廣播Intent匹配的BroadcastReceiver,都可以收到這條廣播,并且不分先后順序,視為同時(shí)收到,通過Context.sendBroadcast()方法發(fā)送。這種廣播的效率比較高,但缺點(diǎn)是接收器不能將處理結(jié)果傳遞給下一個(gè)接收器,并且無法在中途終止廣播。
Intent intent = new Intent();
//對(duì)應(yīng)BroadcastReceiver中intentFilter的action
intent.setAction("test");
//發(fā)送廣播
sendBroadcast(intent);
有序廣播(Ordered Broadcast)
這是一種同步執(zhí)行的廣播,通過Context.sendOrderedBroadcast()方法發(fā)送,這種廣播發(fā)出后,通過receiver的intent-filter中的android:priority屬性來設(shè)置優(yōu)先級(jí),優(yōu)先級(jí)從-1000~1000,數(shù)越大,優(yōu)先級(jí)越高,使用setResult()方法把結(jié)果傳遞給下一個(gè)接收者,通過getResult()方法獲取上一個(gè)接收者傳遞過來的結(jié)果,并可以通過abortBroadcast()方法丟棄該廣播,使該廣播不再傳遞給下一個(gè)接收者。
粘性廣播(Sticky Broadcast)
粘性廣播通過Context.sendStickBroadcast()方法來發(fā)送,用此方法發(fā)送的廣播會(huì)一直滯留,當(dāng)有匹配此廣播的接收器被注冊(cè)后,該廣播接收器就會(huì)收到此廣播。使用此廣播時(shí),需要獲得BROADCAST_STICKY權(quán)限。(在 android 5.0/api 21后不再推薦使用)
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
系統(tǒng)廣播(System Broadcast)
Android系統(tǒng)中內(nèi)置了多個(gè)系統(tǒng)廣播,只要涉及到手機(jī)的基本操作,基本上都會(huì)發(fā)出相應(yīng)的系統(tǒng)廣播。如:開啟啟動(dòng),網(wǎng)絡(luò)狀態(tài)改變,拍照,屏幕關(guān)閉與開啟,點(diǎn)亮不足等等。每個(gè)系統(tǒng)廣播都具有特定的intent-filter,其中主要包括具體的action,系統(tǒng)廣播發(fā)出后,將被相應(yīng)的BroadcastReceiver接收。系統(tǒng)廣播在系統(tǒng)內(nèi)部當(dāng)特定事件發(fā)生時(shí),有系統(tǒng)自動(dòng)發(fā)出。
本地廣播(Local Broadcast)
以上廣播都屬于全局廣播,發(fā)出去的廣播,只要有匹配的接收者,就可以收到廣播。這樣一來會(huì)造成一些問題,一是消耗性能,二是容易引起安全性的問題,為了能夠簡(jiǎn)單的解決這方面的問題,Android引入了一套廣播本地廣播機(jī)制,使用該機(jī)制發(fā)出的廣播只能夠在本應(yīng)用內(nèi)部進(jìn)行傳遞,并且廣播接收器也只能接收來自本應(yīng)用發(fā)出的廣播。
使用方法
1.注冊(cè)本地廣播接收器
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("test");
if (mReceiver == null) {
mReceiver = new MyReceiver();
LocalBroadcastManager.getInstance(mContext).registerReceiver(mReceiver,intentFilter);
}
2.發(fā)送本地廣播
Intent intent = new Intent();
intent.setAction("test");
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
3.注銷本地廣播接收器
@Override
public void onDestroy() {
if (mReceiver != null) {
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReceiver);
}
super.onDestroy();
}
廣播的注冊(cè)
- 靜態(tài)注冊(cè)(常駐)
靜態(tài)注冊(cè)就是在AndroidManifest中注冊(cè)BroadcastReceiver,并指定它所接收的廣播種類,如下面配置的MyReceiver用來接收開機(jī)廣播
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
- 動(dòng)態(tài)注冊(cè)(非常駐)
@Override
protected void onResume() {
super.onResume();
mReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("test");
registerReceiver(mReceiver, intentFilter); // 注冊(cè)廣播接收器
}
@Override
protected void onPause() {
unregisterReceiver(mReceiver); // 注銷廣播接收器
super.onPause();
}
本文用到的BroadcastReceiver
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
特別聲明
Android 8.0(API級(jí)別26)取消大部分靜態(tài)注冊(cè)廣播,建議使用動(dòng)態(tài)廣播
https://developer.android.google.cn/about/versions/oreo/android-8.0