应用休眠

如果您的应用面向 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 广播接收器中添加重新安排逻辑,该接收器在您的应用退出休眠状态和设备启动后调用。

应用使用情况

以下部分提供了应用使用情况的示例,以及系统不视为应用使用情况的操作示例。

应用使用情况示例

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

在 Android 11 及更高版本上,以下行为也被视为用户交互

  • 用户与 小部件 交互。
  • 用户与通知交互,但取消 通知 除外。

需要注意的是,休眠状态的应用使用情况并不明确地要求用户交互。只要软件包的组件被调用,就被视为应用使用情况。以下是一些例子:

  • 设备或操作系统上的其他应用绑定了服务的应用或内容提供商。例如,输入法编辑器 (IME) 或密码管理器。
  • 软件包中的广播接收器从外部软件包接收显式广播。

非示例

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

系统豁免休眠状态

Android 在某些情况下为系统级应用授予休眠状态豁免。如果您的应用属于以下类别之一,则它将豁免 应用使用情况标准,并且不会休眠。

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

用户豁免休眠状态

如果您预计应用中的核心用例会受到休眠状态的影响,您可以向用户请求豁免应用休眠状态。此豁免适用于用户希望您的应用主要在后台运行的情况,即使用户没有与您的应用交互,例如,当您的应用执行以下操作时

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

要请求豁免,请完成以下部分中的步骤。

检查用户是否已为您的应用禁用休眠状态

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

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

要求用户为您的应用禁用休眠状态

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

  1. 显示一个 UI,向用户解释为什么他们需要为您的应用禁用休眠状态。
  2. 调用 createManageUnusedAppRestrictionsIntent() API,如 API 代码示例 中所示。此 API 会创建一个意图,在设置中加载“应用信息”屏幕。从此处,用户可以关闭您的应用的休眠状态。

    重要的是,您在发送此意图时调用 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