日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android o 跨进程广播,[Android] Android O 广播限制

發布時間:2023/12/19 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android o 跨进程广播,[Android] Android O 广播限制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題

因為項目需要遷移到8.0平臺,發現有一個系統應用打不開,從log發現如下描述:

BroadcastQueue: Background execution not allowed: receiving Intent {...}

實際上,在Android O,像下面的隱式廣播都不再起作用:

sendBroadcast(new Intent("this.is.an.implicit.broadcast"));

通常來講,這個廣播會被所有注冊這個action的receiver接收到。即便是在Android O版本,還有兩類receiver仍然會接收這個廣播:

targetSdkVersion <= 25的應用

通過registerReceiver()注冊的并有已經啟動的進程的應用

但是通過Manifest文件靜態注冊的BroadcastReceiver是不會接收這個廣播的,反而會打印出一些開頭提到的log

W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.commonsware.cwac.cam2.demo flg=0x4000010 (has extras) } to com.commonsware.android.sysevents.pkg/.OnPackageChangeReceiver

癥結

這個問題看起來可能與電池有關,因為自從Android 6.0中引入Doze模式以來,各種后臺處理會引起類似現象。但事實上,電池問題是次要的,真正的原因是進程混亂。

對此谷歌工程師是這樣反饋的:

為了幫助了解發生了什么,需要澄清一下,此更改的目的并不直接與電池使用有關,而是要解決平臺中長期存在的問題:處于內存壓力下的設備可能會進入錯誤的內存抖動狀態。這些狀態通常是由于廣播引起的:某些廣播或廣播的發送相對頻繁,許多應用程序正在通過清單進行監聽(因此需要啟動以接收它),但是沒有足夠的RAM來保留所有狀態這些應用程序的進程在緩存中進行處理,因此,每次發送廣播時,系統最終都會不斷地在各個進程中進行跳動。無論設備當前是否已接通電源,這都是一個問題。實際上,這在Android TV設備(始終插上電源)上可能經常會成為問題,因為它們的RAM往往很緊!

這就好理解了,尤其是很多開發者為了喚醒自己的app,注冊了非常多的靜態廣播,每當系統發送一個廣播時,就會出現喚醒很多app的情況,又因為系統內存有限,啟動一些app后另一些app又被殺掉。這樣不僅耗電,還影響使用性能。

Android O 廣播限制

如果應用注冊了BroadcastReceiver,則每次發送廣播的時候,應用的BroadcastReceiver都會消耗資源。如果多個應用注冊了接收基于系統事件的廣播,就會出現,觸發廣播的系統事件會導致所有應用快速的連續消耗資源,從而降低用戶體驗。為了緩解這個問題,Android N對廣播施加了一些限制,而Android O讓這些限制更加嚴格。

Android N做的限制

Android 7.0 及其更高版本不再接收CONNECTIVITY_ACTION的靜態廣播(在清單注冊的receiver)。但是如果是通過Context.registerReceiver()注冊的動態廣播,相關BroadcastReceiver還是可以接收到CONNECTIVITY_ACTION廣播。

應用無法再發送或者接收ACTION_NEW_PICTURE或ACTION_NEW_VIDEO廣播了。這項優化影響所有的App,不只是針對Android 7.0。

Android O進一步的限制

在Android 8.0 或更高版本的應用無法繼續在其AndroidManifest中為隱式廣播注冊BroadcastReceiver。 隱式廣播是一種不專門針對該應用的廣播。 例如,ACTION_PACKAGE_REPLACED就是一種隱式廣播,因為該廣播將被發送給所有已注冊偵聽器,讓后者知道設備上的某些軟件包已被替換。 不過,ACTION_MY_PACKAGE_REPLACED不是隱式廣播,因為不管已為該廣播注冊偵聽器的其他應用有多少,它都會只被發送給軟件包已被替換的應用。

應用可以繼續在它們的清單中注冊顯式廣播。

應用可以在運行時使用Context.registerReceiver()為任意廣播(不管是隱式還是顯式)注冊接收器。

需要簽名權限的廣播不受此限制所限,因為這些廣播只會發送到使用相同證書簽名的應用,而不是發送到設備上的所有應用。

在許多情況下,之前注冊隱式廣播的應用使用JobScheduler作業可以獲得類似的功能。 例如,一款社交照片應用可能需要不時地執行數據清理,并且傾向于在設備連接到充電器時執行此操作。 之前,應用已經在清單中為ACTION_POWER_CONNECTED注冊了一個接收器;當應用接收到該廣播時,它會檢查清理是否必要。 為了遷移到 Android 8.0 或更高版本,應用將該接收器從其清單中移除。 應用將清理作業安排在設備處于空閑狀態和充電時運行。

例外的隱式廣播

很多隱式廣播當前已不受此限制所限。 應用可以繼續在其清單中為這些廣播注冊接收器,不管應用適配哪個 API 級別。

注意:即使這些隱式廣播仍然可以在后臺工作,但你應該盡量避免對它們注冊監聽。

ACTION_LOCKED_BOOT_COMPLETED,ACTION_BOOT_COMPLETED 因為這些廣播只在開機時發送一次,并且很多app需要接收這個廣播來安排作業等操作。

ACTION_USER_INITIALIZE,”android.intent.action.USER_ADDED”,”android.intent.action.USER_REMOVED” 這些廣播被privileged權限所保護,大多數普通app并收不到這些廣播。

“android.intent.action.TIME_SET”, ACTION_TIMEZONE_CHANGED, ACTION_NEXT_ALARM_CLOCK_CHANGED 當時間、時區或鬧鐘有變化時,時鐘應用會需要接收這些廣播以更新時鐘。

ACTION_LOCALE_CHANGED 這個廣播只會在定位變化的時候發送,并不會很頻繁。有些應用會需要這些定位變化來更新數據。

ACTION_USB_ACCESSORY_ATTACHED,ACTION_USB_ACCESSORY_DETACHED,ACTION_USB_DEVICE_ATTACHED,ACTION_USB_DEVICE_DETACHED 如果應用程序需要了解這些與USB相關的事件,那么除了注冊廣播之外,目前沒有其他好的選擇。

ACTION_CONNECTION_STATE_CHANGED,ACTION_CONNECTION_STATE_CHANGED,ACTION_ACL_CONNECTED,ACTION_ACL_DISCONNECTED 如果應用收到這些藍牙事件的廣播,則用戶體驗不太可能會受到影響。

ACTION_CARRIER_CONFIG_CHANGED,TelephonyIntents.ACTION_SUBSCRIPTION_CHANGED,TelephonyIntents.SECRET_CODE_ACTION,ACTION_PHONE_STATE_CHANGED,ACTION_PHONE_ACCOUNT_REGISTERED,ACTION_PHONE_ACCOUNT_UNREGISTERED OEM電話應用程序可能需要接收這些廣播。

LOGIN_ACCOUNTS_CHANGED_ACTION 一些應用程序需要了解登錄帳戶的更改,以便它們可以為新帳戶和更改的帳戶設置計劃的操作。

ACTION_ACCOUNT_REMOVED 擁有帳戶可見性的應用在刪除帳戶后會收到此廣播。 如果這是應用程序需要執行的唯一帳戶更改,則強烈建議應用程序使用此廣播,而不要使用不建議使用的LOGIN_ACCOUNTS_CHANGED_ACTION。

ACTION_PACKAGE_DATA_CLEARED 僅當用戶從“設置”中明確清除其數據時才發送,因此廣播接收器不太可能嚴重影響用戶體驗。

ACTION_PACKAGE_FULLY_REMOVED 某些應用可能需要在刪除另一個軟件包后更新其存儲的數據; 對于這些應用,沒有什么好辦法可以注冊此廣播。 Note: 其他與包相關的廣播(例如,ACTION_PACKAGE_REPLACED)不受新限制。 這些廣播非常普遍,因此可能會對性能產生影響,因此將其排除在外。

ACTION_NEW_OUTGOING_CALL 響應用戶發出呼叫而采取行動的應用需要接收此廣播。

ACTION_DEVICE_OWNER_CHANGED 該廣播不是經常發送; 一些應用程序需要接收它,以便他們知道設備的安全狀態已更改。

ACTION_EVENT_REMINDER 由calendar provider發送,以將事件提醒發布到日歷應用程序。 由于日歷提供程序不知道日歷應用程序是什么,因此此廣播必須是隱式的。

ACTION_MEDIA_MOUNTED,ACTION_MEDIA_CHECKING,ACTION_MEDIA_UNMOUNTED,ACTION_MEDIA_EJECT,ACTION_MEDIA_UNMOUNTABLE,ACTION_MEDIA_REMOVED,ACTION_MEDIA_BAD_REMOVAL 這些廣播是由于用戶與設備的物理交互(安裝或刪除存儲卷)或作為啟動初始化的一部分(隨著可用卷被掛載)而發送的,因此它們并不常見,通常在用戶的控制之下 。

SMS_RECEIVED_ACTION,WAP_PUSH_RECEIVED_ACTION SMS收件人apps依賴這些廣播。

Android O問題的解決方案

檢查在應用的清單中定義的BroadcastReceiver。 如果清單里為顯式廣播聲明了接收器,則必須予以替換。 可能的解決方法包括:

通過調用Context.registerReceiver()動態創建BroadcastReceiver而不是在清單中聲明一個靜態的BroadcastReceiver。

使用JobSchedular檢查條件是否會觸發隱式廣播。

如果在單個進程中使用廣播在應用程序組件之間進行通信,請切換為使用LocalBroadcastManager。

如果使用廣播在自己的多個進程中的應用程序組件之間進行通信,請切換為使用顯式廣播。

如果你想接收系統發送的隱式廣播(例如ACTION_PACKAGE_ADDED),建議保持targetSdkVersion為25或更低。

如果非要發送隱式廣播,則可以通過查找接收方并發送各個顯式廣播來突破禁令:

private static void sendImplicitBroadcast(Context ctxt, Intent i) { PackageManager pm=ctxt.getPackageManager(); List matches=pm.queryBroadcastReceivers(i, 0); for (ResolveInfo resolveInfo : matches) { Intent explicit=new Intent(i); ComponentName cn= new ComponentName(resolveInfo.activityInfo.applicationInfo.packageName, resolveInfo.activityInfo.name); explicit.setComponent(cn); ctxt.sendBroadcast(explicit); } }

官方文檔建議:在大多數情況下,應用都可以使用JobScheduler克服這些限制。 這種方法允許應用安排其在未活躍運行時執行工作,不過仍能夠使系統可以在不影響用戶體驗的情況下安排這些作業。 Android 8.0 提供針對JobScheduler的多項改進,讓用戶可以更輕松地使用計劃作業取代 Service 和BroadcastReceiver

總結

以上是生活随笔為你收集整理的android o 跨进程广播,[Android] Android O 广播限制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。