Android 跨應用廣播通信全攻略

在 Android 開發中,廣播(Broadcast)是一種非常常用的組件間通信機制,既可以在應用內部解耦模塊,也可以在多個應用之間傳遞消息。

但是隨着 Android 版本的演進,特別是8.0+(API 26)之後,廣播的使用方式有了很多限制和坑。

今天我們結合一個實際場景,來系統梳理一下跨應用廣播的正確用法。

1. 廣播的分類

Android 中的廣播按發送/接收方式主要有兩類:

分類

註冊方式

特點

靜態註冊

Manifest 配置

進程未啓動時也能接收(部分系統廣播受限),App 會被系統喚醒

動態註冊

代碼中註冊

只能在進程運行時接收,生命週期跟隨註冊者,靈活但需手動管理

2. Android 8.0+ 的限制

從Android 8.0(API 26)開始,大部分隱式廣播(未指定包名/組件的廣播)禁止靜態註冊。

比如:

在 8.0+ 中,Manifest靜態註冊的自定義接收器將收不到此廣播。

但以下情況不受限制:

顯式廣播(指定包名或組件名)

系統允許的部分廣播(如BOOT_COMPLETED、PACKAGE_ADDED等)

應用內部廣播(LocalBroadcast)

顯式廣播就是明確指定接收方,例如指定包名:

優點:

不受 Android 8.0+ 靜態註冊限制

安全性高,不會被第三方應用接收

投遞效率高,只發給目標應用

缺點:

只能發給指定的應用,廣播範圍受限

如果只要求在應用運行時接收廣播,可以在Application中動態註冊:

優點

不受 Android 8.0 隱式廣播限制

靈活,可在運行時按需註冊

缺點

應用進程未啓動時無法接收

A 應用發送:

B 應用接收(Application 中動態註冊):

適用:B 已啓動或後臺常駐時實時接收

6. 讓未啓動的應用也能接收

如果希望B 即使沒啓動也能收到廣播,必須:

在Manifest中靜態註冊接收器

廣播必須是顯式廣播

B 應用:

有時 A 需要在收到系統廣播(如BOOT_COMPLETED)後,把信息轉發給 B:

需求

推薦方案

進程未啓動也能接收

靜態註冊 + 顯式廣播

應用已運行,實時接收

Application 中動態註冊

只發給一個應用

顯式廣播(setPackage/setComponent)

多個應用都要接收

隱式廣播(注意 8.0+ 限制)

9.爲什麼setIntent()必須調用

singleTask+FLAG_ACTIVITY_CLEAR_TOP場景下的Intent 參數傳遞流程圖,爲什麼setIntent()必須調用?

**不調用setIntent()**:getIntent()永遠是第一次啓動時的舊數據。

**調用setIntent()**:getIntent()會返回最新一次啓動傳進來的參數。

所以:

Android 8.0+ 對靜態註冊隱式廣播限制很大,跨應用通信優先用顯式廣播

動態註冊靈活,但依賴進程常駐

靜態註冊 + 顯式廣播是喚醒未啓動應用的唯一通用方式

系統廣播可以作爲觸發器,把消息中轉給目標應用