問題解決記錄
最近發(fā)現(xiàn)了一個問題,我們的APK只能夠接收待機(jī)下去的廣播,而接收不到待機(jī)起來的廣播。這就很奇怪了,于是便找到了系統(tǒng)發(fā)送待機(jī)和待機(jī)起來廣播的相關(guān)類。
frameworks\base\services\java\com\android\server\power\Notifier.java
從里面找到下面這段代碼,可以看到對于開機(jī)和待機(jī)廣播發(fā)送的代碼其實是一樣的。
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
既然如此,按理說我們的應(yīng)用是可以接到到兩個廣播才對啊,不然就應(yīng)該兩個都收不到。于是便進(jìn)一步分析自己的應(yīng)用。分析后來發(fā)現(xiàn),接受待機(jī)廣播是靜態(tài)注冊的,而接收待機(jī)起來的廣播是動態(tài)注冊的。這時候可以注意到,兩個 TAG 里面有一個Intent.FLAG_RECEIVER_REGISTERED_ONLY。
我們查了一下,發(fā)現(xiàn)如果發(fā)送廣播時設(shè)置了這個標(biāo)志,那只會調(diào)用靜態(tài)注冊了的接收器——BroadcastReceiver組件不會被啟動。所以這里就很明白了,因為我們需要比較快的接收到待機(jī)廣播,從而做出處理,所以這里我們采用了優(yōu)先級較高的動態(tài)注冊,這樣會一定程度上的防止接收不到廣播的問題。那么要解決這個問題,只要在發(fā)送待機(jī)起來廣播的時候把相應(yīng)的TAG去掉就好,所以修改后代碼如下:
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
關(guān)于廣播接收器的一些參考資料
廣播接收器注冊的兩種形式
- 靜態(tài)注冊
非常駐型廣播,也就是說廣播跟隨activity的生命周期。注意: 在activity結(jié)束前,移除廣播接收器。 - 動態(tài)注冊
常駐型,也就是說當(dāng)應(yīng)用程序關(guān)閉后,如果有信息廣播來,程序也會被系統(tǒng)調(diào)用自動運(yùn)行
廣播的類型:
-
有序廣播
- 優(yōu)先級高的先接收
- 同優(yōu)先級的廣播接收器,動態(tài)優(yōu)先于靜態(tài)
- 同優(yōu)先級的同類廣播接收器,靜態(tài):先掃描的優(yōu)先于后掃描的,動態(tài):先注冊的優(yōu)先于后注冊的。
-
普通廣播
- 無視優(yōu)先級,動態(tài)廣播接收器優(yōu)先于靜態(tài)廣播接收器
- 同優(yōu)先級的同類廣播接收器,靜態(tài):先掃描的優(yōu)先于后掃描的,動態(tài):先注冊的優(yōu)先于后注冊的。