应用休眠

如果您的应用以 Android 11(API 级别 30)或更高版本为目标平台,并且用户几个月未与您的应用互动,系统会将您的应用置于休眠状态。系统会优化存储空间而非性能,并保护用户数据。此系统行为与用户从系统设置中手动强制停止应用时发生的情况类似。

休眠的影响

如表 1 所示,休眠的影响取决于您应用的目标 SDK 版本以及您的应用运行所在的设备。

表 1. 休眠对您的应用的影响
目标 SDK 版本 设备特性 休眠效果
Android 12 或更高版本 运行 Android 12 或更高版本

您应用的运行时权限会被重置。此操作的效果与用户在系统设置中查看某个权限并将其应用的访问级别更改为拒绝相同。

您的应用无法从后台运行作业或提醒。

您的应用无法接收推送通知,包括通过Firebase Cloud Messaging发送的高优先级消息。

应用缓存中的所有文件都会被移除。

Android 11 运行 Android 11 您应用的运行时权限会被重置。
Android 11 运行 Android 6.0(API 级别 23)到 Android 10(API 级别 29)(含)的版本,并由 Google Play 服务提供支持

您应用的运行时权限会被重置。

此行为将于 2021 年 12 月生效。如需了解详情,请参阅这篇博文,其中介绍了如何使权限自动重置功能支持数十亿台设备

应用退出休眠时的系统行为

当用户下次与您的应用互动时,您的应用将退出休眠状态,并可以再次创建作业、提醒和通知。

但是,系统不会为您的应用执行以下操作:

  1. 重新授予您应用的运行时权限。

    用户必须重新授予这些权限才能让您的应用使用。

  2. 重新安排在您的应用进入休眠状态之前已安排的任何作业、提醒和通知。

    为更轻松地支持此工作流程,请使用 WorkManager。您还可以在 ACTION_BOOT_COMPLETED 广播接收器中添加重新安排逻辑,该接收器在您的应用退出休眠且设备启动后调用。

应用使用情况

以下各节提供了应用使用情况的示例,以及系统不视为应用使用情况的动作示例。

应用使用情况示例

当您的应用中的某个activity恢复时,系统会将此事件视为用户互动。因此,系统会延长您的应用进入休眠状态之前的时间。

在 Android 11 及更高版本中,以下行为也被视为用户互动:

  • 用户与小部件互动。
  • 用户与通知互动,但解除通知除外。

需要注意的是,休眠的应用使用情况不明确要求用户互动。只要软件包的某个组件被调用,它仍然被视为应用使用情况。一些示例如下:

  • 设备上或操作系统中由另一个应用绑定的具有服务或内容提供商的应用。例如,输入法编辑器 (IME) 或密码管理器。
  • 软件包中的广播接收器接收来自外部软件包的明确广播。

非示例

如果您的应用只表现出以下列表中描述的行为,则您的应用将在几个月后进入休眠状态:

系统对休眠的豁免

在某些用例中,Android 授予应用系统级休眠豁免权。如果您的应用属于以下类别之一,则它不受应用使用标准的约束,并且不会休眠。

未显示在启动器上的应用
任何在启动器上没有活动快捷方式磁贴的应用。
工作资料应用
用户安装在工作资料上的任何应用。请注意,如果同一个应用也存在于个人资料中,则只有工作资料应用会获得豁免。
设备政策控制器
控制设备上本地设备政策和系统应用的应用。
运营商特权应用
移动运营商预加载到设备上并认为对合同服务义务必要的任何应用,例如语音邮件或客户服务应用。
第三方安装程序应用
必要时用于自动更新其已安装应用的第三方应用商店。

用户对休眠的豁免

如果您预计应用中的某个核心用例会受到休眠的影响,您可以向用户请求应用休眠豁免。此豁免对于用户期望您的应用主要在后台工作(即使没有用户互动)的情况很有用,例如您的应用执行以下任何操作时:

  • 通过定期报告家庭成员的位置来提供家庭安全。
  • 在设备和您应用的服务器之间同步数据。
  • 与智能设备(例如电视)通信。
  • 配对到配套设备,例如手表。

要请求豁免,请完成以下各节中的步骤。

检查用户是否已为您的应用停用休眠

要检查用户是否已为您的应用停用休眠,请使用 getUnusedAppRestrictionsStatus() API。

有关如何在您的应用中使用此 API 的更多详细信息,请参阅此页面上的API 代码示例

要求用户为您的应用停用休眠

如果用户尚未为您的应用停用休眠,您可以向用户发送请求。为此,请完成以下步骤:

  1. 显示一个用户界面,向用户解释为什么他们需要为您的应用停用休眠。
  2. 调用 createManageUnusedAppRestrictionsIntent() API,如API 代码示例所示。此 API 会创建一个 intent,用于加载“设置”中的应用信息屏幕。用户可以从此屏幕关闭您应用的休眠功能。

    重要提示:发送此 intent 时,务必调用 startActivityForResult(),而不是 startActivity()

    如表 2 所示,该选项的位置和名称取决于安装您应用的设备的特性:

    表 2. 停用应用休眠的选项
    设备特性 选项所在页面 要关闭的选项名称
    运行 Android 13 或更高版本 应用信息 如果应用未使用,则暂停其活动
    运行 Android 12 应用信息 移除权限并释放空间
    运行 Android 11 应用信息 > 权限 如果应用未使用,则移除权限
    运行 Android 6.0 到 Android 10(含)的版本,并由 Google Play 服务提供支持 Play 应用 > 菜单 > Play 保护机制 > 未使用应用的权限 如果应用未使用,则移除权限

API 代码示例

此代码示例展示了如何检查是否为您的应用启用了休眠功能,以及请求用户为您的应用停用休眠功能的正确方法。

Kotlin

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

旧版平台 API

操作系统还包含一个用于与休眠功能交互的 API。但是,该 API 仅适用于运行 Android 11 或更高版本的设备;该 API 不处理回溯到早期 Android 版本的休眠功能。因此,我们不建议使用此 API。

如果您需要为了兼容性目的暂时继续使用该 API,以下列表显示了如何使用它:

手动调用休眠行为

要测试您的应用在系统将其置于休眠状态后的行为,请完成以下步骤:

  1. (仅限 Android 12 及更高版本)在您的设备上启用休眠行为

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. 设置系统等待进入休眠的默认时长。这样,您可以在测试后恢复它:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. 缩短系统等待的时间。在以下示例中,系统被修改为:在您停止与应用互动后仅一秒钟,您的应用就会进入休眠状态:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. 通过运行以下命令,等待测试设备上的所有启动时广播完成:

    adb shell am wait-for-broadcast-idle
    

    当广播完成时,此命令将返回消息:All broadcast queues are idle!

  5. 手动调用应用休眠过程

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (仅限 Android 12 及更高版本)使用以下方法之一确认应用是否已休眠:

    • 观察测试设备是否显示一条通知,指示未使用的应用已休眠。
    • 运行以下命令:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. 恢复系统在将您的应用置于休眠状态之前等待的默认时长

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold