0. Background Service Limitations 介绍

为了减少系统资源的使用,Android 8 引入了「Background Execution Limits」,其中对于 Service 的限制是,不能调用 startService() 方法启动一个后台 Service,bindService() 无影响。

满足下面条件中的一项,则被定义为前台应用:

一个应用进入后台后,会有几分钟的时间窗口期,之后会进入 idle 状态。进入 idle 状态后,后台 Service 被受限,而且系统会停止已经启动的 Service,就像调用 stopSelf() 一样。

当应用在处理用户可见任务情况下,会临时加入到白名单中,并持续数分钟。例如:

注意,IntentService 也是 Service,所以也被受限。因此,Android Support Library 26.0.0 中介绍了 JobIntentService 类,它提供与 IntentService 类似的功能,但是使用 JobSchedule 实现。

大部分情况下, 可以用 JobSchedule 替换后台 Service。

启动前台 Service 的方法是 startForegroundService(),Service 启动后需要在 5 秒内调用 startForeground() 方法启动用户可见的 Notification,否则系统会停止该 Service,并报出 ANR。

1. 应用后台执行限制的源码分析 (Android 9.0)

1.1 ActivityManagerService.getAppStartModeLocked()

一个应用是否可以后台执行(Background Execution),与 ActivityManagerServicegetAppStartModeLocked() 方法返回结果相关。返回结果在 ActivityManager 中定义。

/** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */
public static final int APP_START_MODE_NORMAL = 0;

/** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: delay running until later. */
public static final int APP_START_MODE_DELAYED = 1;

/** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: delay running until later, with
 * rigid errors (throwing exception). */
public static final int APP_START_MODE_DELAYED_RIGID = 2;

/** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: disable/cancel pending
 * launches; this is the mode for ephemeral apps. */
public static final int APP_START_MODE_DISABLED = 3;