android 8.0 移除靜態註冊廣播
Android O 前瞻 - 是時候和 Implict Broadcast 說再見了
簡評:果然省電是 Android O 的第一任務。
日前,Android O 預覽版已經發布,這裡就來介紹下 Android O 中對 Broadcast 的改變。
Android O 對於系統廣播(Broadcast)的改變歸根結底都是為了進一步的節省功耗。Google 在 Android Marshmallo (6.0, API level 23) 中引入了 Doze and App Standby 來改進 Android 系統的電池表現。
Doze 限制所有的應用程式在特殊的時間視窗中執行耗電任務,而 App Standby 會限制最少使用 App 的網路活動。同時 Google 開始建議開發者使用在 Android Nougat (7.0) 中,Google 移除了三項隱式廣播(Implict Broadcast)(CONNECTIVITY_ACTION, ACTION_NEW_PICTURE, ACTION_NEW_VIDEO),而在 Android O 中除了這裡列出的,其餘所有的隱式廣播都被移除了。
Google 認為應用程式在其 manifest 中註冊了太多沒必要的 BraodcastReceiver,導致了不必要的耗電。比如,很多的應用和第三方 SDK 都會監聽 CONNECTIVITY_ACTION 廣播。當你離開家,斷開了家裡的 wifi。Android 傳送 CONNECTIVITY_ACTION
並且,因為 wifi 不再可用,手機會連線上行動網路,廣播又會發送一遍,回到家再連上 wifi,相同的事再次發生。
鑑於開發者們肯定更多的只是考慮自己的應用,你可以想象一下手機裡的每個應用可能都會去監聽網路狀態變更、是否拍攝了新照片、安裝了新應用、開始充電等等事件。因為這些 App 都在 AndroidManifest.xml 中註冊接收這些廣播,所以它們總是能被喚醒接收這些廣播,即使不在前臺,甚至沒有執行。Google 也意識到隱式廣播被濫用了,因此才會在 Android O 中清除了如此多的隱式廣播。
那在 Android O 中我們應該怎麼做呢?
1. 確定哪些 Broadcast 是隱式(Implict)的
根據官方文件,所有沒有直接和你應用相關的廣播都是隱式的。比如文件中舉例的 ACTION_PACKAGE_REPLACED,會在每個新應用安裝時被廣播。因此,像 ACTION_MY_PACKAGE_REPLACED 這樣的就是顯式廣播(explicit Broadcast),因為其只會在你的應用更新時才會進行廣播。
絕大多數我們監聽的廣播都是隱式的。
2. 確定你的應用是否會被影響
這裡列出的是沒有被移除的隱式廣播,也就是如果你的應用只是監聽了這些廣播的話,那麼恭喜你,你的應用不需要改。
3. 如果應用確實監聽了這些被移除的隱式廣播,JobScheduler 來解救你
JobScheduler 完美適配 Doze 和 App Standby,可以根據定義的條件來執行任務,比如:
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);
不過,JobSchedular 只支援 Android API 21 及以上,如果你的應用需要支援以下版本的系統,官方建議可以使用 FirebaseJobDispatcher。
這裡推薦可以用 Evernote 的 Android-Job。其能夠根據當前系統,當系統為 Marshmallow 及以上時使用 JobSchedular。當版本沒達到時,根據是否集成了 Google Play Service 來使用 GCMNetworkManager 或 AlarmManager。