查看: 2859|回复: 0

[手机开发] Android8.0以上广播限制

发表于 2018-1-31 08:00:00

Android上同时运行的应用越多,对系统造成的负担越大。为了降低发生性能变差的几率,Android 8.0 对应用在用户不与其直接交互时可以执行的操作施加了限制。
应用在两个方面受到限制:
? 后台服务限制:处于空闲状态时,应用可以使用的后台服务存在限制。这些限制不适用于前台服务。
? 广播限制:除了有限的例外广播,应用不能使用清单(AndroidManifest.xml)注册隐式广播。但仍然可以在运行时动态注册这些广播,并且可以使用清单注册专门针对它们的显式广播。
注:默认情况下,这些限制仅适用于针对API级别为O (API 26) 的应用。不过,用户可以从Settings为任意应用启用这些限制,即使应用并不是以 O (API 26)为目标平台。在大多数情况下,应用都可以使用JobScheduler克服这些限制。

广播限制实际上从android7.0 (API 25)上就开始了,只是那时它只限制了”CONNECTIVITY_ACTION”, “ ACTION_NEW_PICTURE or ACTION_NEW_VIDEO”,这3条广播。
到了8.x,限制的广播范围更加严格了。
? 针对 Android 8.0 (API 26) 的应用无法继续在其清单中为隐式广播注册广播接收器 (隐式广播是一种不专门针对该应用的广播) 。
例如,ACTION_PACKAGE_REPLACED 就是一种隐式广播,因为它将发送到注册的所有侦听器,让后者知道设备上的某些软件包已被替换。不过,ACTION_MY_PACKAGE_REPLACED 不是隐式广播,因为不管已为该广播注册侦听器的其他应用有多少,它都会只发送到软件包已被替换的应用。
? 应用可以继续在它们的清单中注册显式广播。(也就是明确指定了接收者组件的广播)
? 应用可以在运行时使用 Context.registerReceiver() 为任意广播(不管是隐式还是显式)注册接收器。
? 需要签名权限的广播不受此限制所限,因为这些广播只会发送到使用相同证书签名的应用,而不是发送到设备上的所有应用。

在许多情况下,之前注册隐式广播的应用使用 JobScheduler 可以获得类似的功能。默认情况下,这些更改仅影响针对 O 的应用。 不过,用户可以从 Settings为任意应用启用这些限制,即使应用并不是以 O 为目标平台。
例如,一款应用可能需要不时地执行数据清理,并且倾向于在设备连接到充电器时执行此操作。之前,应用已经在清单中为 ACTION_POWER_CONNECTED 注册了一个接收器;当应用接收到该广播时,它会检查清理是否必要。 为了迁移到 Android 8.0,应用将该接收器从其清单中移除。改用JobScheduler 将清理工作安排在设备处于空闲状态和充电时运行。
约有30个左右的隐式广播得到豁免,当前均不受此限制所限。应用可以继续在其AndroidManifest.xml清单中为这些广播注册接收器,不管应用针对哪个API级别。
除了这些豁免的广播及广播白名单中的Action外,其它广播默认都将会进行上述限制
豁免广播列表如下:
? ACTION_LOCKED_BOOT_COMPLETED、ACTION_BOOT_COMPLETED
豁免原因:这些广播只在首次启动时发送一次,并且许多应用都需要接收此广播以便进行作业、闹铃等事项的安排。

? ACTION_USER_INITIALIZE、"android.intent.action.USER_ADDED"、"android.intent.action.USER_REMOVED"
这些广播受特权保护,因此大多数正常应用无论如何都无法接收它们。

? "android.intent.action.TIME_SET"、ACTION_TIMEZONE_CHANGED
时钟应用可能需要接收这些广播,以便在时间或时区变化时更新闹铃。

? ACTION_LOCALE_CHANGED
只在语言区域发生变化时发送,并不频繁。应用可能需要在语言区域发生变化时更新其数据。

? ACTION_USB_ACCESSORY_ATTACHED、ACTION_USB_ACCESSORY_DETACHED、ACTION_USB_DEVICE_ATTACHED、ACTION_USB_DEVICE_DETACHED
如果应用需要了解这些 USB 相关事件的信息,目前尚未找到能够替代注册广播的可行方案。

? ACTION_HEADSET_PLUG
由于此广播只在用户进行插头的物理连接或拔出时发送,因此不太可能会在应用响应此广播时影响用户体验。

? ACTION_CONNECTION_STATE_CHANGED
与 ACTION_HEADSET_PLUG 类似,应用接收这些蓝牙事件的广播时不太可能会影响用户体验。

? ACTION_CARRIER_CONFIGCHANGED、TelephonyIntents.ACTION*_SUBSCRIPTION_CHANGED、"TelephonyIntents.SECRET_CODE_ACTION"
原始设备制造商(OEM)电话应用可能需要接收这些广播。

? ACTION_DEVICE_STORAGE_LOW、ACTION_DEVICE_STORAGE_OK
一些应用可能需要通过删除数据来响应存储空间不足广播。例如,照片应用可能会删除已备份至云存储空间的旧照片。

? LOGIN_ACCOUNTS_CHANGED_ACTION
一些应用需要了解登录帐号的变化,以便为新帐号和变化的帐号设置计划操作。

? ACTION_PACKAGE_DATA_CLEARED
只在用户显式地从 Settings 清除其数据时发送,因此广播接收器不太可能严重影响用户体验。

? ACTION_PACKAGE_FULLY_REMOVED
一些应用可能需要在另一软件包被移除时更新其存储的数据;对于这些应用,尚未找到能够替代注册此广播的可行方案。
注:其他软件包相关广播(例如:ACTION_PACKAGE_REPLACED)不能免受这些新增限制。 这些广播相当常见,豁免它们可能会影响性能。

? ACTION_NEW_OUTGOING_CALL
执行操作来响应用户打电话行为的应用需要接收此广播。

? ACTION_DEVICE_OWNER_CHANGED
此广播发送得不是很频繁;一些应用需要接收它,以便知晓设备的安装状态发生了变化。

? ACTION_EVENT_REMINDER
由日历提供程序发送,用于向日历应用发布事件提醒。因为日历提供程序不清楚日历应用是什么,所以此广播必须是隐式广播。



回复

使用道具 举报