小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Android 廣播的那些事兒

 codingSmart 2021-10-22

前言

Android App 可以接收來自系統(tǒng)和其他 App 的廣播消息,也可以向它們發(fā)送廣播消息,比較類似于“發(fā)布-訂閱”的設(shè)計(jì)模式,本文主要介紹廣播的類型,如何注冊(cè)廣播,如何發(fā)送廣播以及使用廣播需要注意的一些事兒。

廣播的分類

  • 無序廣播
    沒有順序的廣播,廣播的接收方?jīng)]有嚴(yán)格的順序可言,不可中斷。

  • 有序廣播
    在注冊(cè)時(shí)可指定優(yōu)先級(jí),優(yōu)先級(jí)高的廣播接收者優(yōu)先收到廣播,優(yōu)先級(jí)以一個(gè)整數(shù)來標(biāo)識(shí),數(shù)值越大優(yōu)先級(jí)越高??芍袛啵稍傩揎?。

  • 粘滯廣播
    發(fā)出的廣播會(huì)滯留,注冊(cè)時(shí)間可晚于發(fā)送時(shí)間,其他功能與無序廣播相同。

注冊(cè)廣播

編寫一個(gè)廣播接收者,通常是繼承 BroadcastReceiver 并重寫onReceive(Context,Intent) 方法。

編寫完廣播接收者后,就需要進(jìn)行注冊(cè)(訂閱),告訴系統(tǒng)這個(gè)廣播接收者對(duì)哪些廣播感興趣。注冊(cè)的方式有靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)兩種:

  • 在AndroidManifest.xml文件中聲明(靜態(tài)注冊(cè))

  • 通過Java代碼注冊(cè)(動(dòng)態(tài)注冊(cè))

通過動(dòng)態(tài)注冊(cè)的廣播接收者,在宿主(注冊(cè)時(shí)所使用的 Context)的生命周期期間都是有效的。當(dāng)然你也可以在適當(dāng)?shù)臅r(shí)間調(diào)用unregisterReceiver(BroadcastReceiver) 來解除注冊(cè),這個(gè)“適當(dāng)”取決于具體的業(yè)務(wù)需求。例如使用 Activity 的 Context 在onCreate(Bundle) 中注冊(cè)的一個(gè)廣播接收者,可以在 onDestory() 方法回調(diào)時(shí)解除注冊(cè)來防止廣播接收者泄漏。原則:不重復(fù)注冊(cè),不泄露。

以上注冊(cè)的廣播接收者對(duì) android.intent.action.BOOT_COMPLETED 和 jdqm.intent.action.TEST 這兩種action的廣播感興趣,后者是自定義的廣播,前者是開機(jī)完成時(shí)由系統(tǒng)發(fā)出(通常自啟動(dòng)的應(yīng)用會(huì)注冊(cè)這個(gè)廣播),但注冊(cè)這個(gè)廣播須要以下權(quán)限:

發(fā)送廣播

  1. 發(fā)送無序廣播

  1. 發(fā)送有序廣播

  1. 發(fā)送本地廣播

本地廣播只有本應(yīng)用內(nèi)通過LocalBroadcastManager.getInstance(this).registerReceiver 方法注冊(cè)的廣播接收者能收到,具有更高的安全性,效率也更高(不用跨進(jìn)程通信)。

  1. 發(fā)送粘滯廣播

這種類型廣播在 Android6.0 中已經(jīng)被標(biāo)記被過時(shí), 它有不安全(任何 App 都能訪問), 沒有保護(hù) (任何 App 都能修改)等問題。另外發(fā)送這種廣播需要以下權(quán)限

接收順序

  1. 對(duì)于無序廣播,動(dòng)態(tài)注冊(cè)的廣播接收者會(huì)先收到,可以從源碼中得到理論支撐。在BroadcastQueue類中有兩個(gè)集合

然后在其 processNextBroadcast(boolean fromMsg) 方法中,首先是處理了 mParallelBroadcasts 集合。

  1. 對(duì)于有序廣播,優(yōu)先級(jí)高的接受者先收到,如果優(yōu)先級(jí)相同,順序就是不確定的。先收到的接收者可以調(diào)用 abortBroadcast()來中斷此廣播,后續(xù)優(yōu)先級(jí)較低的接受者將無法收到。除了中斷還可以調(diào)用 setResultXxx()方法來往廣播添加數(shù)據(jù),后續(xù)的接收者可以讀取這些數(shù)據(jù)。

安全性與實(shí)踐

  1. 如果你的廣播不需要發(fā)送給本應(yīng)用以外的組件,使用LocalBroadcastManager來發(fā)送廣播,這樣安全性和效率都比較高

  2. 靜態(tài)注冊(cè)有可能造成大量的App啟動(dòng),這將會(huì)影響系統(tǒng)的性能,所以盡量使用動(dòng)態(tài)注冊(cè)來替代靜態(tài)注冊(cè)。這一點(diǎn)Android系統(tǒng)就做出了很好的示范,比如 CONNECTIVITY_ACTION 這個(gè)廣播只發(fā)送給動(dòng)態(tài)注冊(cè)的廣播接收者。

  3. 不在廣播的Intent中包含敏感的信息,因?yàn)橹灰?cè)了這個(gè)廣播就能讀取到這些信息。你可以通過以下3中方式來獲得一定的安全性。

  • 通過使用權(quán)限來發(fā)送廣播,這樣只有聲明了該權(quán)限的應(yīng)用才能收到廣播。但是你很難確保你的權(quán)限不被泄漏。

  • Android4.0及以上版本,在發(fā)送廣播的時(shí)候可以通過setPackage來指定package(可以指定多個(gè)),這樣只有匹配的package能接受到。

  • 使用LocalBroadcastManager來發(fā)送本地廣播。

  1. 當(dāng)你注冊(cè)了一個(gè)廣播,意味著任何App都可以給你發(fā)送廣播,以下有三點(diǎn)可以限制接收者:

  • 注冊(cè)的時(shí)候增加權(quán)限。

  • 在AndroidManifest.xml注冊(cè)receivers時(shí),將android:exported屬性設(shè)為false。

  • 使用LocalBroadcastManager來注冊(cè)。

  1. action的命名空間是全局的,這意味著action有可能會(huì)與其他App沖突,所以最好是有一個(gè)自己的命名空間。

  2. 因?yàn)閺V播接收者是運(yùn)行在主線程,它應(yīng)該快速地被執(zhí)行并且return,所以不要在onReveive方法中做比較耗時(shí)的操作。

  3. 不要在廣播接收者中啟動(dòng)activitys,這違背了用戶的使用習(xí)慣,特別是不止一個(gè)接收者時(shí)。這種情況下可以考慮展示一個(gè)notification來替代。

其他

  1. 系統(tǒng)廣播的action的完整列表在Android SDK下的 BROADCAST_ACTIONS.TXT,路徑為: Android/sdk/platforms/android-26/data/BROADCAST_ACTIONS.TXT

  2. Android3.1開始,系統(tǒng)的package manager將記錄處于停止?fàn)顟B(tài)的應(yīng)用。默認(rèn)情況下,靜態(tài)注冊(cè)了廣播的處于“停止”狀態(tài)的應(yīng)用,是不會(huì)被啟動(dòng)的,即不會(huì)收到廣播。當(dāng)然你也可以為Intent指定flag來該變這個(gè)行為:

  • FLAG_INCLUDE_STOPPED_PACKAGES:包含處于“停止”狀態(tài)的應(yīng)用;

  • FLAG_EXCLUDE_STOPPED_PACKAGES:不包含處于“停止”狀態(tài)的應(yīng)用;

如果Intent不包含(或都包含)這兩個(gè)flag,則表現(xiàn)形式是包含處于“停止”轉(zhuǎn)態(tài)的應(yīng)用,但是系統(tǒng)默認(rèn)添加了FLAG_EXCLUDE_STOPPED_PACKAGES這個(gè)flag,這一點(diǎn)在源碼中有所體現(xiàn):

ActivityManagerService#broadcastIntentLocked

這就意味著如果你想啟動(dòng)處于“停止”狀態(tài)的應(yīng)用,必須添加FLAG_INCLUDE_STOPPED_PACKAGES這個(gè)flag。那么一個(gè)應(yīng)用在什么情況下會(huì)處于停止?fàn)顟B(tài)?①應(yīng)用首次安裝并且沒有啟動(dòng)過;②被人為地強(qiáng)制停止。開機(jī)完成的廣播就是FLAG_EXCLUDE_STOPPED_PACKAGES這種類型的Intent,這意味著如果你的應(yīng)用被停止了,開機(jī)自啟就會(huì)失效。下一篇文章將從源碼的角度來分析廣播的工作流程。

送書

節(jié)后送書,熱門+暢銷,感謝你與 code小生 一起成長(zhǎng)

微信號(hào):code-xiaosheng

公眾號(hào)

「code小生」

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多