廣播的種類
Android 中的廣播主要可以分為兩種類型,標(biāo)準(zhǔn)廣播和有序廣播。
- 標(biāo)準(zhǔn)廣播:是一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,所有的廣播接收器機(jī)會(huì)都會(huì)在同一時(shí)間接收到這條廣播消息,效率高同時(shí)又無法被截?cái)?/li>
- 有序廣播:是一種同步執(zhí)行的廣播,廣播發(fā)出后,同一時(shí)刻只會(huì)有一個(gè)廣播接收器能夠收到這條廣播消息,當(dāng)這個(gè)廣播接收器中的邏輯執(zhí)行完畢后,廣播才會(huì)繼續(xù)傳遞,所以這種類型的廣播是有先后順序的,優(yōu)先級(jí)高廣播接收器就可以先接收到廣播消息,并且前面的廣播接收器還可以截?cái)嗾趥鬟f的廣播,這樣后面的廣播接收器就無法收到廣播消息了。
廣播的使用
首先要自定義一個(gè)廣播接收器,繼承BroadcastReceiver,然后復(fù)寫onReceive() 方法,像這樣:
public class MyReceiver extends BroadcastReceiver {
public static final String ACTION= "action";
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
//接收廣播后的一些邏輯,這里注意下 onReceive方法是自動(dòng)調(diào)用的
Log.d("MyReceiver", "收到廣播了");
}
}
其次,就要進(jìn)行廣播的注冊,注冊主要有兩種形式:
- 靜態(tài)注冊
- 動(dòng)態(tài)注冊
靜態(tài)注冊:在AndroidManifest.xml中添加注冊
<receiver
android:name=".activity.fourComponents.MyReceiver">
<intent-filter>
<action android:name="myReceiver" />
</intent-filter>
</receiver>
當(dāng)App啟動(dòng)的時(shí)候,會(huì)自動(dòng)將MyReceiver這個(gè)接收器注冊在系統(tǒng)當(dāng)中,當(dāng)收到相應(yīng)的廣播的時(shí)候就會(huì)自動(dòng)調(diào)用MyReceiver 中的onReceive() 方法。
動(dòng)態(tài)注冊:盡量在onResume() 和 onPause()中進(jìn)行廣播的注冊和銷毀
private MyReceiver mMyReceiver;
if (mMyReceiver == null) {
// 實(shí)例化BroadcastReceiver子類 & IntentFilter
mMyReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
//設(shè)置接收廣播的類型
intentFilter.addAction("myReceiver");
//動(dòng)態(tài)注冊:調(diào)用Context的registerReceiver()方法
registerReceiver(mMyReceiver, intentFilter);
}
最后不能忘記要銷毀動(dòng)態(tài)廣播
//廣播動(dòng)態(tài)銷毀
unregisterReceiver(mMyReceiver);
不管是靜態(tài)注冊還是動(dòng)態(tài)注冊,他們的共同點(diǎn):
- 自動(dòng)回調(diào)onReceive() 方法
- 廣播接收器運(yùn)行在UI線程
所以在廣播中不能做耗時(shí)操作,否則就會(huì)導(dǎo)致ANR
靜態(tài)注冊和動(dòng)態(tài)注冊的區(qū)別
靜態(tài)注冊和動(dòng)態(tài)注冊的區(qū)別主要從這三個(gè)方面來看:
- 使用方式
- 特點(diǎn)
- 應(yīng)用場景
使用方式
動(dòng)態(tài)注冊:在代碼中調(diào)用Context.registerReceiver
靜態(tài)注冊:在AndroidManifest.xml通過<receiver>標(biāo)簽聲明
特點(diǎn)
動(dòng)態(tài)注冊:跟隨組件的生命周期變化
靜態(tài)注冊:常駐進(jìn)程中,不受組件生命周期影響(即使應(yīng)用程序關(guān)閉,如果有廣播發(fā)送,程序依然會(huì)被系統(tǒng)喚醒調(diào)用)
應(yīng)用場景
靜態(tài)注冊:需要時(shí)刻監(jiān)聽廣播(比如在性能優(yōu)化時(shí),計(jì)算每隔一段時(shí)間的網(wǎng)絡(luò)訪問量)
動(dòng)態(tài)注冊:需要在特定時(shí)刻接受廣播(可根據(jù)業(yè)務(wù)場景選擇)
廣播接收器更多的是扮演一種打開程序其他組件的角色,例如創(chuàng)建一條狀態(tài)欄通知,或者啟動(dòng)一個(gè)服務(wù)等。
廣播的原理
Android中的廣播使用了觀察者模式,角色分配:
- 消息訂閱者(廣播接受者)
- 消息發(fā)布者(廣播發(fā)布者)
- 消息中心(Activity Manager Service,即AMS)
原理簡述:
- 廣播接收者:通過Binder 機(jī)制在 AMS 注冊
- 廣播發(fā)送者:通過Binder 機(jī)制向 AMS 發(fā)送廣播
- AMS 根據(jù)廣播發(fā)送者要求,在已注冊列表中,尋找合適的廣播接受者
- AMS 將廣播發(fā)送到合適的廣播接收者相應(yīng)的消息循環(huán)隊(duì)列中