忙啊~最近好忙呀。html
忙的我連SystemUI系列的文章推動向蝸牛同樣慢~java
這篇文章偷個閒,記錄下Android8.0上的廣播限制。android
最近在基於Android 8.1的系統項目中有用到靜態註冊廣播去監聽廣播。但是不論我是普通的將Apk install進去抑或是高貴的push到對應的system/priv-app/目錄下,都收不到這個廣播。心態,DUANG,炸了。安全
後來靈光一閃,扒出記憶角落的Android7.0的廣播限制,趕忙Google一下。原來如此,恍然大悟:**Android8.0後,當App targetSDK >= 26,幾乎禁止了全部的隱式廣播的靜態註冊監聽。**特在此記錄,防止我之後又提莫的忘記了。 微信
本篇文章主要講述如下內容,還請拿起小板凳,帶好零食,前來觀賞:網絡
來來來,先科普下,廣播兩種監聽/接收註冊方式和兩種類型,拿小本本記下來,記住了!app
註冊方式:ide
兩種類型:ui
Intent.setComponent()
Intent.setClassName()
Intent.setClass()
new Intent(A.this,B.class)
複製代碼
注意是針對targetSDK >= 26的應用,也就是說,targetSDK小於26的話,暫不受影響this
在Oreo中,爲了進一步提高用戶體驗,進一步節省功耗,對應用在後臺運行時能夠執行的操做又進一步施加了限制。
後臺服務限制:處於空閒狀態時,限制應用的後臺服務。例如:經過靜態註冊接收開機廣播(假設你的設備沒作定製,能收到~),並在onReceive方法中啓動一個Service,在API 26上,是不容許且會報錯的。固然,對於前臺服務,這種限制是不存在的。官方說法是:前臺服務更容易引發用戶注意。
廣播限制:除了有限的例外以外,應用沒法使用清單註冊(靜態註冊)的方式來接收隱式廣播。
這裏多說一句,Android手機的卡頓,很大程度是因爲應用濫用且自私的使用各類手段(權限濫用,廣播註冊,後臺服務常駐等)保活或作一些PY事情。Google顯然很早就意識到這一點,並從Android 6.0 開始就逐步引入各類限制,好比運行時權限和Doze。
若是應用註冊了廣播接收器,那麼每次發送廣播後,應用的廣播接收器就會消耗資源,如RAM,CPU等。若是有不少應用對系統事件廣播註冊廣播接收器,這....,就會很卡的嘛!
因此從Android 7.0 (API 級別 24)開始,就對廣播作了一些限制:
只不過,在Android8.0上,又進一步的加強了限制,除了如下隱式廣播外,其餘全部隱式廣播均沒法經過在AndroidManifest.xml中註冊監聽。參考官網。
// Android 8.0 上不限制的隱式廣播
/** 開機廣播 Intent.ACTION_LOCKED_BOOT_COMPLETED Intent.ACTION_BOOT_COMPLETED */
"保留緣由:這些廣播只在首次啓動時發送一次,而且許多應用都須要接收此廣播以便進行做業、鬧鈴等事項的安排。"
/** 增刪用戶 Intent.ACTION_USER_INITIALIZE "android.intent.action.USER_ADDED" "android.intent.action.USER_REMOVED" */
"保留緣由:這些廣播只有擁有特定系統權限的app才能監聽,所以大多數正常應用都沒法接收它們。"
/** 時區、ALARM變化 "android.intent.action.TIME_SET" Intent.ACTION_TIMEZONE_CHANGED AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED */
"保留緣由:時鐘應用可能須要接收這些廣播,以便在時間或時區變化時更新鬧鈴"
/** 語言區域變化 Intent.ACTION_LOCALE_CHANGED */
"保留緣由:只在語言區域發生變化時發送,並不頻繁。 應用可能須要在語言區域發生變化時更新其數據。"
/** Usb相關 UsbManager.ACTION_USB_ACCESSORY_ATTACHED UsbManager.ACTION_USB_ACCESSORY_DETACHED UsbManager.ACTION_USB_DEVICE_ATTACHED UsbManager.ACTION_USB_DEVICE_DETACHED */
"保留緣由:若是應用須要瞭解這些 USB 相關事件的信息,目前還沒有找到可以替代註冊廣播的可行方案"
/** 藍牙狀態相關 BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED BluetoothDevice.ACTION_ACL_CONNECTED BluetoothDevice.ACTION_ACL_DISCONNECTED */
"保留緣由:應用接收這些藍牙事件的廣播時不太可能會影響用戶體驗"
/** Telephony相關 CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED TelephonyIntents.ACTION_*_SUBSCRIPTION_CHANGED TelephonyIntents.SECRET_CODE_ACTION TelephonyManager.ACTION_PHONE_STATE_CHANGED TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED */
"保留緣由:設備製造商 (OEM) 電話應用可能須要接收這些廣播"
/** 帳號相關 AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION */
"保留緣由:一些應用須要瞭解登陸賬號的變化,以便爲新賬號和變化的賬號設置計劃操做"
/** 應用數據清除 Intent.ACTION_PACKAGE_DATA_CLEARED */
"保留緣由:只在用戶顯式地從 Settings 清除其數據時發送,所以廣播接收器不太可能嚴重影響用戶體驗"
/** 軟件包被移除 Intent.ACTION_PACKAGE_FULLY_REMOVED */
"保留緣由:一些應用可能須要在另外一軟件包被移除時更新其存儲的數據;對於這些應用,還沒有找到可以替代註冊此廣播的可行方案"
/** 外撥電話 Intent.ACTION_NEW_OUTGOING_CALL */
"保留緣由:執行操做來響應用戶打電話行爲的應用須要接收此廣播"
/** 當設備全部者被設置、改變或清除時發出 DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED */
"保留緣由:此廣播發送得不是很頻繁;一些應用須要接收它,以便知曉設備的安全狀態發生了變化"
/** 日曆相關 CalendarContract.ACTION_EVENT_REMINDER */
"保留緣由:由日曆provider發送,用於向日歷應用發佈事件提醒。由於日曆provider不清楚日曆應用是什麼,因此此廣播必須是隱式廣播。"
/** 安裝或移除存儲相關廣播 Intent.ACTION_MEDIA_MOUNTED Intent.ACTION_MEDIA_CHECKING Intent.ACTION_MEDIA_EJECT Intent.ACTION_MEDIA_UNMOUNTED Intent.ACTION_MEDIA_UNMOUNTABLE Intent.ACTION_MEDIA_REMOVED Intent.ACTION_MEDIA_BAD_REMOVAL */
"保留緣由:這些廣播是做爲用戶與設備進行物理交互的結果:安裝或移除存儲卷或當啓動初始化時(當可用卷被裝載)的一部分發送的,所以它們不是很常見,而且一般是在用戶的掌控下"
/** 短信、WAP PUSH相關 Telephony.Sms.Intents.SMS_RECEIVED_ACTION Telephony.Sms.Intents.WAP_PUSH_RECEIVED_ACTION 注意:須要申請如下權限才能夠接收 "android.permission.RECEIVE_SMS" "android.permission.RECEIVE_WAP_PUSH" */
"保留緣由:SMS短信應用須要接收這些廣播"
複製代碼
呼,終於列完了,以上。能夠說寫的比官網還全~
建議收藏一波防止之後用的到哈。
按照官方推薦,對於隱式廣播,經過如下方法進行替換。
Context.registerReceiver()
註冊廣播接收器而不是在清單中聲明接收器。我選擇動態註冊的方式來處理這個問題。
好了,關於Oreo的廣播限制的嘮嗑就先嘮到這裏。
最近受到一位小夥伴的啓發,獲得一句話:努力的人,運氣和機遇每每都不會差!
共勉!
最後,歡迎關注微信公衆號:猿溼Xoong
開心的進行Android高質量乾貨分享
[1] Android Oreo 後臺執行限制 https://developer.android.com/about/versions/oreo/background#broadcasts
[2] Android Oreo Implicit Broadcast Exceptions https://developer.android.com/guide/components/broadcast-exceptions
[3] Android中顯式和隱式intent的特色和區別 https://blog.csdn.net/u014177843/article/details/50596863
[4] Android O行爲變動--隱式廣播限制 https://blog.csdn.net/hqocshheqing/article/details/76850164