1. 程式人生 > >android 8.0 移除靜態註冊廣播

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 開始建議開發者使用
JobScheduler
來安排所有的後臺任務。

在 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。

結論

不要再監聽 Android 移除的隱式通知,使用 JobSchedular, FirebaseJobDispatcher 或 Android-Job 來實現相同的功能。