If an app registers to receive broadcasts, the app's receivers consume resources each time a broadcast is sent. This can cause problems if multiple apps register to receive system event-based broadcasts: a system event that triggers a broadcast can cause all apps to consume resources in rapid succession, degrading the user experience. To alleviate this problem, Android 7.0 (API level 24) imposes some restrictions on broadcasting, as described in Background optimizations . Android 8.0 (API level 26) tightens these restrictions.
Implicit Broadcast Limited
Apps targeting Android 8.0 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. An _Implicit broadcast_ is a broadcast that is not specific to the app.
If the current implicit broadcast cannot be distributed to the statically registered receiver, a log similar to the following will be printed:
W BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.PACKAGE_RESTARTED dat=package:com.android.soundrecorder flg=0x10 (has extras) } to com.xiaomi.misubscreenui/.receiver.LightDeviceStatusReceiver
The main solutions are as follows:
- Apps can continue to register for explicit broadcasts in their manifest.
- Applications can register receivers for any broadcast (either implicitly or explicitly) at runtime using Context.registerReceiver() .
- Broadcasts that require signing permissions are exempt from this restriction because they are only sent to apps signed with the same certificate, not to all apps on the device.
The summary is: send display broadcast, dynamic registration, and declare signature authority.
// 静态注册的receiver
if (!skip) {
// android o+直接返回APP_START_MODE_DELAYED_RIGID
final int allowed = mService.getAppStartModeLOSP(
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
// 不允许启动
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
Slog.w(TAG, "Background execution disabled: receiving "
+ r.intent + " to "
+ component.flattenToShortString());
skip = true;
// 不允许后台接收
} else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
// 隐式广播&不在豁免名单中&不需要签名权限
|| (r.intent.getComponent() == null
&& r.intent.getPackage() == null
&& ((r.intent.getFlags()
& Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
&& !isSignaturePerm(r.requiredPermissions))) {
mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
component.getPackageName());
Slog.w(TAG, "Background execution not allowed: receiving "
+ r.intent + " to "
+ component.flattenToShortString());
skip = true;
}
}
}
Implicit Broadcast Exemption
Apps targeting API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest due to background execution restrictions in Android 8.0 (API level 26). However, several broadcasts are currently exempt from these restrictions. Regardless of which API level your app targets, you can continue to register listeners for the following broadcasts.
Note : Although these implicit broadcasts are still running in the background, you should avoid registering listeners for them.
That is, the following implicit broadcasts can also be received if they are registered in the background list file
- ACTION_BOOT_COMPLETED
@BroadcastBehavior(includeBackground = true)
public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
- The intents in the allow-implicit-broadcast list will be added to broadcastIntentLocked
if (getBackgroundLaunchBroadcasts().contains(action)) {
if (DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
}
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
}
Reason for Exemption These broadcasts are only sent once on first launch, and many applications need to receive this broadcast for scheduling jobs, alarm clocks, etc.
- ACTION_USER_INITIALIZE、“android.intent.action.USER_ADDED”、“android.intent.action.USER_REMOVED”
These broadcasts are protected by privileged permissions, so most normal apps cannot receive them.
- “android.intent.action.TIME_SET”、ACTION_TIMEZONE_CHANGED、ACTION_NEXT_ALARM_CLOCK_CHANGED
When the time, time zone, or alarm changes, the clock app may need to receive these broadcasts to update the alarm.
Sent only when the locale changes, which is not common. Apps may need to update their data when locales change.
- ACTION_USB_ACCESSORY_ATTACHED、ACTION_USB_ACCESSORY_DETACHED、ACTION_USB_DEVICE_ATTACHED、ACTION_USB_DEVICE_DETACHED
If an application needs to know about these USB-related events, there is currently no good alternative to registering for broadcasts.
- ACTION_CONNECTION_STATE_CHANGED、ACTION_CONNECTION_STATE_CHANGED、ACTION_ACL_CONNECTED、ACTION_ACL_DISCONNECTED
If the app receives broadcasts for these Bluetooth events, the user experience is unlikely to be affected.
- 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 phone applications may need to receive these broadcasts.
Some apps need to know about login account changes in order to set up scheduled actions for new and changed accounts.
Apps with account visibility will receive this broadcast after the account has been removed. Applications that only need to perform actions on this account change are strongly encouraged to use this broadcast instead of the deprecated LOGIN_ACCOUNTS_CHANGED_ACTION .
Only sent when the user explicitly clears data in Settings, so broadcast receivers are unlikely to significantly impact user experience.
Some apps may need to update their stored data when other packages are removed; for these apps, there is no good alternative to registering for this broadcast.
Note : Other package-related broadcasts (such as ACTION_PACKAGE_REPLACED ) are not exempt from the new limit. These broadcasts are common, and exemptions can affect performance.
Apps need to receive this broadcast to take appropriate action when the user makes a phone call.
This live stream is sent infrequently; some applications need to receive it to know that the security state of the device has changed.
Sent by the calendar provider to post an event reminder to the calendar application. This broadcast must be implicit since the calendar provider does not know what a calendar application is.
- ACTION_MEDIA_MOUNTED、ACTION_MEDIA_CHECKING、ACTION_MEDIA_UNMOUNTED、ACTION_MEDIA_EJECT、ACTION_MEDIA_UNMOUNTABLE、ACTION_MEDIA_REMOVED、ACTION_MEDIA_BAD_REMOVAL
These broadcasts are sent during a user's physical interaction with the device (mounting or removing a storage volume) or during boot initialization (when an available volume mounts), and are usually under user control.
SMS receiver applications need to rely on these broadcasts.
Common evasion methods
The sender adds the FLAG_RECEIVER_INCLUDE_BACKGROUND flag
Note that this flag is a hide api, and third-party apps will not be able to access it, but you can specify a flag value of 0x01000000
@SystemApi
public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);