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+ 對靜態註冊隱式廣播限制很大,跨應用通信優先用顯式廣播
動態註冊靈活,但依賴進程常駐
靜態註冊 + 顯式廣播是喚醒未啓動應用的唯一通用方式
系統廣播可以作爲觸發器,把消息中轉給目標應用