Android 基礎(chǔ)知識3:四大組件之 Broadcast(廣播)

Broadcast

目錄

目錄

一、Broadcast 的定義

Broadcast 是一種廣泛運(yùn)用的、在應(yīng)用程序之間傳輸信息的機(jī)制,Android 中的廣播與傳統(tǒng)意義上的電臺廣播類似,一個(gè)廣播可以有任意個(gè)接收者,當(dāng)然也可能不被任何應(yīng)用程序所接收。廣播機(jī)制是一個(gè)典型的發(fā)布-訂閱模式,也就是觀察者模式。

廣播機(jī)制最大的特點(diǎn)是發(fā)送方不關(guān)心接收方是否接受到數(shù)據(jù),也不關(guān)心接收方是如何處理數(shù)據(jù)的,通過這樣的方式來達(dá)到接、收雙方的完全解耦。

(一)廣播的三要素:
  1. 廣播(Broadcast):用于發(fā)送廣播
  2. 廣播接收器(BroadcastReceiver):用于接收廣播
  3. 意圖內(nèi)容(Intent):用于保存廣播相關(guān)信息的媒介
(二)廣播的分類:
  1. 普通廣播
  2. 有序廣播
  3. 本地廣播
  4. Sticky 廣播

二、普通廣播

普通廣播是完全異步的,通過 Context 的 sendBroadcast() 函數(shù)來發(fā)送,消息傳遞的效率比較高,但所有的 receivers(接收器)的執(zhí)行順序不確定。缺點(diǎn)是:接收者不能將處理結(jié)果傳遞給下一個(gè)接收者,并且無法終止廣播 Intent 的傳播,直到?jīng)]有與之匹配的廣播接收器為止。

下面我們來寫一個(gè)普通廣播:

step1:定義一個(gè)廣播接收器

public class MyBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null) {
            return;
        }

        String name = intent.getStringExtra("name");
        Log.d(TAG, name);
    }
}

step2:注冊廣播

注冊廣播的方式有兩種:靜態(tài)注冊動態(tài)注冊

  • 靜態(tài)注冊:即在 AndroidManifest.xml 文件中進(jìn)行注冊
<receiver
  android:name=".MyBroadcastReceiver"
  android:enabled="true"
  android:exported="true">
  <intent-filter>
    <action android:name="com.cyy.broad" />
  </intent-filter>
</receiver>

enabled 設(shè)置為 true 意味著能夠接受到信息,exportedtrue 意味著能夠接收到外部 apk 廣播發(fā)送的信息。

  • 動態(tài)注冊:即在代碼中進(jìn)行注冊
    public void registerHelloBroadcast() {
        receiver = new MyBroadcastReceiver();
        registerReceiver(receiver, new IntentFilter("com.cyy.broad"));
    }

如果使用動態(tài)注冊,那么不要忘記在執(zhí)行 onDestroy 時(shí)注銷廣播:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (receiver != null) {
            unregisterReceiver(receiver);
        }
    }

step3:發(fā)送廣播 sendBroadcast()

如果是靜態(tài)注冊的廣播:

Intent intent = new Intent("com.cyy.broad");
ComponentName componentName = new ComponentName("com.chenyouyu.broadcastdemo",
                        "com.chenyouyu.broadcastdemo.MyBroadcastReceiver");
intent.setComponent(componentName);
intent.putExtra("name", "hello");
sendBroadcast(intent);

如果是動態(tài)注冊的廣播:

Intent intent = new Intent("com.cyy.broad");
intent.putExtra("name", "hello");
sendBroadcast(intent);

當(dāng)我們調(diào)用了 sendBroadcast() 后,會調(diào)用 MyBroadcastReceiver 的 onReceive 函數(shù)。

三、有序廣播

有序廣播通過 Context.sendOrderedBroadcast() 來發(fā)送,所以的廣播接收器按照優(yōu)先級依次執(zhí)行,廣播接收器的優(yōu)先級通過 receiver 的 intent-filter 中的 android:priority 屬性來設(shè)置,數(shù)值越大優(yōu)先級越高(參數(shù)為 -1000 ~ 1000)。當(dāng)廣播接收器接收到廣播后,可以使用 setResult() 函數(shù)來將結(jié)果傳遞給下一個(gè)廣播接收器,然后通過 getResult() 函數(shù)來取得上一個(gè)廣播接收器返回的結(jié)果,并可以使用 abortBroadcast() 函數(shù)來讓系統(tǒng)丟棄該廣播,使該廣播不再傳遞到別的廣播接收器。

設(shè)置廣播的優(yōu)先級代碼示例:

      <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.cyy.broad" />
            </intent-filter>
        </receiver>

關(guān)于 android:priority 的取值范圍,官網(wǎng)給出的是 -1000 ~ 1000 ,但是看到很多人設(shè)置成2147483647(Integer.MAX_VALUE)這個(gè)值,可能因?yàn)?android:priority 的屬性值是 integer 類型,系統(tǒng)會拿這個(gè)值和其他值做比較,結(jié)果怎么都是它最大了。

發(fā)送有序廣播:

sendOrderedBroadcast(intent,null);

四、本地廣播

在 21 版的 Support v4 包中新增本地廣播,也就是 LocalBroadcastManager 。之前廣播都是全局的,所有應(yīng)用程序都可以接收到,這樣就會帶來安全隱患。但是,有的時(shí)候我們并不需要把自己的應(yīng)用內(nèi)的信息廣播給所有應(yīng)用,而只是進(jìn)程內(nèi)使用,現(xiàn)在使用 Support v4 包中的 LocalBroadcastManager 就能夠?qū)崿F(xiàn)限于應(yīng)用內(nèi)的廣播。

它的用法很簡單,只需要把調(diào)用 context 的 sendBroadcast、registerReceiver、unregisterReceiver 的地方替換為 LocalBroadcastManager.getInstance(Context context) 中對應(yīng)的函數(shù)即可:

函數(shù) 作用
LocalBroadcastManager.getInstance(context).registerReceiver(receiver,intentFilter) 注冊 Receiver
LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver) 注銷 Receiver
LocalBroadcastManager.getInstance(context).sendBroadcast(intent) 發(fā)送異步廣播
LocalBroadcastManager.getInstance(context).sendBroadcastSync(intent) 發(fā)送同步廣播

五、sticky 廣播

sticky 廣播通過 Context.sendStickyBroadcast() 函數(shù)來發(fā)送,用此函數(shù)發(fā)送的廣播會一直滯留,當(dāng)有匹配此廣播的廣播接收器被注冊后,該廣播接收器就會收到此條廣播。使用此函數(shù)發(fā)送廣播時(shí),需要獲得 BROADCAST_STICKY 權(quán)限:

<uses-permission android:name="android.permission.BROADCAST_STICKY"/>

sendStickyBroadcast() 只保留最后一條廣播,并且一直保留下去,這樣即使已經(jīng)有廣播接收器處理了該廣播,當(dāng)再有匹配的廣播接收器被注冊時(shí),此廣播仍會被接收。如果你只想處理一遍該廣播,可以通過 removeStickyBroadcast() 函數(shù)實(shí)現(xiàn)。


參考資料:

  1. 《Android開發(fā)進(jìn)階從小工到專家》何紅輝
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2.1 Activity 2.1.1 Activity的生命周期全面分析 典型情況下的生命周期:在用戶參與的情況下...
    AndroidMaster閱讀 3,281評論 0 8
  • 廣播接收器 是Android的四大組件之一,可見廣播在Android中的重要性; 1. 什么是廣播? 廣播(Bro...
    Lost_Robot閱讀 2,055評論 2 10
  • 定義 廣播接收器是一個(gè)全局的監(jiān)聽器,屬于四大組件之一。Android廣播分為兩個(gè)角色:廣播發(fā)送者、廣播接收者。 應(yīng)...
    呂注意閱讀 1,528評論 0 1
  • 前言Android四大組件重要性已經(jīng)不言而喻了,今天談?wù)劦氖茿ndroid中的廣播機(jī)制。在我們上學(xué)的時(shí)候,每個(gè)班級...
    陳祥_閱讀 957評論 0 5
  • 1.Android廣播機(jī)制概述 Android廣播分為兩個(gè)方面:廣播發(fā)送者和廣播接收者,通常情況下,Broadca...
    IT小魔女的故事閱讀 617評論 0 2

友情鏈接更多精彩內(nèi)容