第五章 全局大喇叭,詳解廣播機(jī)制

5.1廣播機(jī)制簡(jiǎn)介

廣播分為標(biāo)準(zhǔn)廣播和有序廣播

  • 標(biāo)準(zhǔn)廣播:異步執(zhí)行廣播,廣播發(fā)出后,所有的廣播接收器都會(huì)幾乎在同時(shí)接收到,沒(méi)有先后順序.效率較高,但是無(wú)法攔截.
  • 有序廣播:同步執(zhí)行廣播,同一時(shí)刻只有一個(gè)廣播接收器能夠接收到該廣播,且僅當(dāng)該接收器的邏輯執(zhí)行結(jié)束后再回繼續(xù)傳遞.優(yōu)先級(jí)高的先收到廣播消息(同等優(yōu)先級(jí)則隨機(jī)選擇一個(gè)),前面的接收器可以截?cái)嗾趥鞑サ膹V播.

5.2接收系統(tǒng)廣播

廣播接收器可以對(duì)自己感興趣的廣播進(jìn)行注冊(cè).注冊(cè)廣播分為靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè).

  • 動(dòng)態(tài)注冊(cè):在代碼中注冊(cè).
  • 靜態(tài)注冊(cè):在AndroidManifest.xml中注冊(cè).

onReceive()內(nèi)不允許添加過(guò)多邏輯或耗時(shí)操作.通常半夜打開(kāi)其他程序或組件的角色.

  • 廣播接收器中不允許開(kāi)線(xiàn)程.
  • onReceive()運(yùn)行時(shí)間過(guò)程而沒(méi)有結(jié)束時(shí),程序會(huì)報(bào)錯(cuò).

5.2.1動(dòng)態(tài)注冊(cè)監(jiān)聽(tīng)網(wǎng)絡(luò)變化

步驟:
1.新建一個(gè)廣播接收器內(nèi)部類(lèi).
2.繼承BroadcastReceiver.
3.重寫(xiě)父類(lèi)的onReceive(),intenFilter中寫(xiě)監(jiān)聽(tīng)的廣播.
注意:

  • 僅在軟件啟動(dòng)后才有作用.
  • onDestroy()中加上unregiReceive(),用于銷(xiāo)毀接收器.
    示例:
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);

5.2.2靜態(tài)注冊(cè)實(shí)現(xiàn)開(kāi)機(jī)啟動(dòng)

步驟:
1.新建廣播接收器類(lèi).
2.繼承BroadcastReceiver.
3.AndroidManifest.xml中注冊(cè),注冊(cè)中填寫(xiě)監(jiān)聽(tīng)的廣播.
注意:

  • 該方法可以實(shí)現(xiàn)開(kāi)機(jī)自啟
  • 注冊(cè)在<application>內(nèi)
    示例:
<receiver android:name=".BootCompleteReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

5.3發(fā)送自定義廣播

5.3.1發(fā)送標(biāo)準(zhǔn)廣播

步驟:
1.new Intent,參數(shù)為廣播名.
2.sendBroadcast(intent).
注意:

  • 可以在intent中傳遞一些數(shù)據(jù)被廣播接收器.
    示例:
Intent intent = new Intent("com.wjoker.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);

5.3.2發(fā)送有序廣播(和截?cái)鄰V播

步驟:
1.發(fā)送廣播使用sendOrderBroadcast().
2.在注冊(cè)接收器處加權(quán)限.
3.onReceive()處使用abortBroadcast().(截?cái)?
步驟:

Intent intent = new Intent("com.wjoker.broadcasttest.MY_BROADCAST");
sendOrderedBroadcast(intent,null);
<receiver android:name=".MyBroadcastReceive">
    <intent-filter android:priority="100">
        <action android:name="com.wjoker.broadcasttest.MY_BROADCAST"/>
    </intent-filter>
</receiver>
public void onReceive(Context context, Intent intent) {
    Toast.makeText(context,"test",Toast.LENGTH_SHORT).show();
    abortBroadcast();
}

5.4使用本地廣播

用于解決安全性問(wèn)題.只接受本應(yīng)用內(nèi)的廣播或只在本應(yīng)用內(nèi)傳遞.
步驟:
1.通過(guò)LocalBroadcastManager對(duì)廣播進(jìn)行管理(發(fā)送/接收).
注意:

  • 本地廣播無(wú)法通過(guò)靜態(tài)方式注冊(cè).
  • 比系統(tǒng)全局廣播效率更高.
    示例:
private LocalBroadcastManager localBroadcastManager;

localBroadcastManager = LocalBroadcastManager.getInstance(this);

Intent intent = new Intent("com.wjoker.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);//發(fā)送本地廣播
intentFilter = new IntentFilter();
intentFilter.addAction("com.wjoker.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter);// 注冊(cè)本地廣播監(jiān)聽(tīng)器

總結(jié)

1.廣播根據(jù)是否存在接收順序可分為標(biāo)準(zhǔn)廣播和有序廣播;根據(jù)范圍可分為全局廣播和本地廣播.
2.有序廣播可以截?cái)鄰V播;本地廣播是安全且高效的.
3.廣播接收器注冊(cè)分為動(dòng)態(tài)注冊(cè)(代碼中注冊(cè),啟動(dòng)后開(kāi)始監(jiān)聽(tīng))和靜態(tài)注冊(cè)(AndroidManifest.xml中注冊(cè),隨時(shí)監(jiān)聽(tīng)).
4.onReceive()中不允許開(kāi)多線(xiàn)程且運(yùn)行過(guò)長(zhǎng)會(huì)報(bào)錯(cuò).
5.動(dòng)態(tài)注冊(cè)的監(jiān)聽(tīng)內(nèi)容在interFace.addAction()中添加,靜態(tài)注冊(cè)在<action>中添加.
6.要銷(xiāo)毀接收器.
7.發(fā)送標(biāo)準(zhǔn)廣播,使用sendBroadcast(intent).
8.發(fā)送有序廣播使用sendOrderBroadcast(intent),要在接收器里設(shè)置優(yōu)先級(jí).
9.使用abortBroadcast()截?cái)鄰V播(僅有序).
10.本地廣播使用LocalBroadcastManager管理(接收/發(fā)送).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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