android 8.0+ background broadcast limit

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:

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.

These broadcasts are protected by privileged permissions, so most normal apps cannot receive them.

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.

If an application needs to know about these USB-related events, there is currently no good alternative to registering for broadcasts.

If the app receives broadcasts for these Bluetooth events, the user experience is unlikely to be affected.

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.

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);

Send display broadcast, specify Component or Package

The receiver uses dynamic registration Receiver

Guess you like

Origin blog.csdn.net/xiaoyantan/article/details/128389499