Android O 前瞻 - 是時(shí)候和 Implict Broadcast 說(shuō)再見(jiàn)了

簡(jiǎn)評(píng):果然省電是 Android O 的第一任務(wù)。

日前,Android O 預(yù)覽版已經(jīng)發(fā)布,這里就來(lái)介紹下 Android O 中對(duì) Broadcast 的改變。

Android O 對(duì)于系統(tǒng)廣播(Broadcast)的改變歸根結(jié)底都是為了進(jìn)一步的節(jié)省功耗。Google 在 Android Marshmallo (6.0, API level 23) 中引入了 Doze and App Standby 來(lái)改進(jìn) Android 系統(tǒng)的電池表現(xiàn)。
Doze 限制所有的應(yīng)用程序在特殊的時(shí)間窗口中執(zhí)行耗電任務(wù),而 App Standby 會(huì)限制最少使用 App 的網(wǎng)絡(luò)活動(dòng)。同時(shí) Google 開(kāi)始建議開(kāi)發(fā)者使用 JobScheduler 來(lái)安排所有的后臺(tái)任務(wù)。

在 Android Nougat (7.0) 中,Google 移除了三項(xiàng)隱式廣播(Implict Broadcast)(CONNECTIVITY_ACTION, ACTION_NEW_PICTURE, ACTION_NEW_VIDEO),而在 Android O 中除了這里列出的,其余所有的隱式廣播都被移除了。

Google 認(rèn)為應(yīng)用程序在其 manifest 中注冊(cè)了太多沒(méi)必要的 BraodcastReceiver,導(dǎo)致了不必要的耗電。比如,很多的應(yīng)用和第三方 SDK 都會(huì)監(jiān)聽(tīng) CONNECTIVITY_ACTION 廣播。當(dāng)你離開(kāi)家,斷開(kāi)了家里的 wifi。Android 發(fā)送 CONNECTIVITY_ACTION 廣播,結(jié)果幾乎所有的應(yīng)用都會(huì)被喚醒并對(duì)此作出反應(yīng)。

并且,因?yàn)?wifi 不再可用,手機(jī)會(huì)連接上移動(dòng)網(wǎng)絡(luò),廣播又會(huì)發(fā)送一遍,回到家再連上 wifi,相同的事再次發(fā)生。

鑒于開(kāi)發(fā)者們肯定更多的只是考慮自己的應(yīng)用,你可以想象一下手機(jī)里的每個(gè)應(yīng)用可能都會(huì)去監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài)變更、是否拍攝了新照片、安裝了新應(yīng)用、開(kāi)始充電等等事件。因?yàn)檫@些 App 都在 AndroidManifest.xml 中注冊(cè)接收這些廣播,所以它們總是能被喚醒接收這些廣播,即使不在前臺(tái),甚至沒(méi)有運(yùn)行。Google 也意識(shí)到隱式廣播被濫用了,因此才會(huì)在 Android O 中清除了如此多的隱式廣播。

那在 Android O 中我們應(yīng)該怎么做呢?

1. 確定哪些 Broadcast 是隱式(Implict)的

根據(jù)官方文檔,所有沒(méi)有直接和你應(yīng)用相關(guān)的廣播都是隱式的。比如文檔中舉例的 ACTION_PACKAGE_REPLACED,會(huì)在每個(gè)新應(yīng)用安裝時(shí)被廣播。因此,像 ACTION_MY_PACKAGE_REPLACED 這樣的就是顯式廣播(explicit Broadcast),因?yàn)槠渲粫?huì)在你的應(yīng)用更新時(shí)才會(huì)進(jìn)行廣播。

絕大多數(shù)我們監(jiān)聽(tīng)的廣播都是隱式的。

2. 確定你的應(yīng)用是否會(huì)被影響

這里列出的是沒(méi)有被移除的隱式廣播,也就是如果你的應(yīng)用只是監(jiān)聽(tīng)了這些廣播的話(huà),那么恭喜你,你的應(yīng)用不需要改。

3. 如果應(yīng)用確實(shí)監(jiān)聽(tīng)了這些被移除的隱式廣播,JobScheduler 來(lái)解救你

JobScheduler 完美適配 Doze 和 App Standby,可以根據(jù)定義的條件來(lái)執(zhí)行任務(wù),比如:

ComponentName myService = new ComponentName(this, MyService.class);
JobInfo myJob = new JobInfo.Builder(myService)
        .setRequiresCharging(true)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .setPersisted(true)
        .build();

JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(myJob);

不過(guò),JobSchedular 只支持 Android API 21 及以上,如果你的應(yīng)用需要支持以下版本的系統(tǒng),官方建議可以使用 FirebaseJobDispatcher。

這里推薦可以用 Evernote 的 Android-Job。其能夠根據(jù)當(dāng)前系統(tǒng),當(dāng)系統(tǒng)為 Marshmallow 及以上時(shí)使用 JobSchedular。當(dāng)版本沒(méi)達(dá)到時(shí),根據(jù)是否集成了 Google Play Service 來(lái)使用 GCMNetworkManager 或 AlarmManager。

結(jié)論
不要再監(jiān)聽(tīng) Android 移除的隱式通知,使用 JobSchedular, FirebaseJobDispatcher 或 Android-Job 來(lái)實(shí)現(xiàn)相同的功能。

原文:It’s time to kiss goodbye to your implicit BroadcastReceivers

日?qǐng)?bào)延伸閱讀

歡迎關(guān)注

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

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

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