App Standby 是一种 Android 机制,它将不常用的应用转入待机模式,限制其后台活动以节省电量。与 Doze Mode(设备休眠模式)不同,App Standby 在单个应用级别工作,独立于屏幕状态和运动。根据规范 Android Developers, 2025,App Standby 可以通过阻止不常用应用的后台工作将其能耗降低高达 70%。
要点
App Standby 是 Android 能源管理系统的一个组件,在 Android 6.0(API 23)中引入,并在 Android 9(API 28)中进行了重大重新设计。其任务是确定哪些应用用户不常使用,并限制其后台活动:网络请求、同步、JobScheduler 和 AlarmManager。与 Doze 不同,App Standby 不依赖于屏幕状态或设备运动。
系统将应用分为四个 bucket(级别):Active、Working Set、Frequent 和 Rare。每个级别决定了后台活动受到多大限制。级别之间的转换基于应用使用模式自动进行:用户打开应用的频率、接收通知的频率、与小工具的交互频率。
App Standby 与 Doze Mode 协同工作,但不能替代它。如果 Doze 在设备闲置时限制所有应用的后台活动,那么 App Standby 则独立于设备状态限制特定应用。具有 Rare 级别的应用即使在手机活跃使用时也会受到限制,如果用户几天没有打开它的话。
从 Android 9(API 28)开始,Google 引入了 App Standby Buckets——一种带有数值的正式分类。系统使用机器学习来预测应用的下一次启动。如果模型预测应用将在未来几小时内打开,它将获得 Active bucket。如果预测表明使用频率低——则分配 Rare。
App Standby 分析多个因素来确定 bucket:用户上次打开应用的时间、交互频率(每天/每周启动次数)、接收 FCM 通知、桌面上活动小工具的存在以及 AlarmManager 订阅。应用未使用的时间越长,其 bucket 越低,限制越严格。
系统服务 UsageStatsManager 收集应用使用统计信息,并将其传递给 StandbyController——一个为每个应用计算 bucket 的框架组件。StandbyController 还考虑系统事件:应用更新后,其 bucket 会重置为 Active 几天,以便用户可以评估新功能。
重要特性:App Standby 不会终止应用的进程,而是限制其后台能力。如果用户与应用交互(bucket Active),应用继续运行。一旦用户最小化应用并且不返回,系统开始计算不活动时间,并可能将 bucket 降低到 Working Set 或 Frequent。
接收 FCM high-priority 消息可以暂时将应用的 bucket 提升到 Active。这使应用能够无限制地执行任务(处理消息、同步数据)。然而,处理完成后,bucket 返回到原始值。Google 建议使用此机制传递重要通知,而不是保持应用 “活着”。
App Standby 使用四个级别(bucket)对应用进行分类。每个级别确定后台任务的延迟时间:级别越低,延迟越长。系统根据过去 7-14 天收集的使用统计信息自动在级别之间移动应用。
| Bucket | 描述 | JobScheduler 延迟 | 网络 |
|---|---|---|---|
| Active | 应用正在被活跃使用 | 无延迟 | 完全访问 |
| Working Set | 定期使用,但非当前 | 最多 2 小时 | 在窗口中 |
| Frequent | 经常使用,但不是每天 | 最多 4 小时 | 在窗口中 |
| Rare | 不常用的应用 | 最多 24 小时 | 在窗口中 |
Active — 用户最近交互过的应用(启动、收到通知或使用小工具)。在此 bucket 中没有限制:JobScheduler 立即启动,网络可用,AlarmManager 精确工作。应用保持在 Active,直到用户停止与其交互几个小时。
Working Set — 应用定期使用(每周几次)。后台任务延迟最多 2 小时。Frequent — 应用每月使用几次。延迟最多 4 小时。在这两个级别中,网络仅在维护窗口中可用,AlarmManager 可能被延迟。JobScheduler 在最近的窗口中执行任务。
Rare — 最严格的级别,分配给用户超过 30 天未打开的应用。后台任务延迟达到 24 小时。在维护窗口之外网络被完全封锁,AlarmManager 仅以 setAndAllowWhileIdle() 标志工作,限制为每 9 分钟 1 次。FCM high-priority 通知仍会送达,但无法提升 bucket。
App Standby 对几类后台操作施加限制。与 Doze 不同,App Standby 的限制独立于屏幕状态和充电器工作。开发者应在设计应用时考虑这些限制,特别是如果目标用户不规律地使用应用。
JobScheduler — App Standby 影响的主要 API。根据 bucket,任务执行延迟在 2 到 24 小时之间。WorkManager(在 API 23+ 上使用 JobScheduler)也受到这些延迟的影响。对于时间关键型任务,请使用 Expedited Work,它在后台启动 Foreground Service 并且不依赖于 bucket。
处于 Working Set、Frequent 和 Rare bucket 中的应用不能随时进行任意网络请求。系统仅在与 Doze 同步的维护窗口中允许网络访问。要发送关键数据,请使用 FCM high-priority,然后在维护窗口中进行同步。
AlarmManager 在 App Standby 中受与 Doze 相同的规则约束:精确闹钟(setExact())被延迟,setAndAllowWhileIdle() 限制为每 9 分钟 1 次。对于 Rare bucket,延迟可能达到 24 小时,这使得 AlarmManager 不适合在不常用的应用中精确调度任务。
豁免 可以通过两种方式获得:通过用户电池设置(手动白名单)或通过系统 Intent ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS。然而,Google 严格规范对豁免的访问——没有充分理由获得豁免的应用可能会被 Google Play 拒绝。
用户可以通过设置 → 应用 → [应用] → 电池 → 优化 → 不优化手动禁用特定应用的限制。这会完全消除所选应用的 App Standby 和 Doze 限制。开发者可以向用户显示说明或系统对话框,但不能强制将应用添加到例外中。
带有通知的 Foreground Service 会自动从 App Standby 获得临时豁免。只要服务运行并显示通知,应用就会转移到 Active bucket,无论其实际级别如何。服务停止后,bucket 返回到原始值。这是保证后台工作而无需请求系统例外的最可靠方式。
请求 白名单 仅对具有关键后台功能的应用有意义:实时导航、健康监测、VoIP 通话、设备保护。对于大多数应用,使用 Foreground Service 或 WorkManager 就足够了。如果应用在没有明显需求的情况下请求豁免,Google Play 可能会拒绝发布。
// 请求从 App Standby 豁免
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:\${applicationContext.packageName}")
}
// 检查当前状态
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
val isIgnoring = powerManager.isIgnoringBatteryOptimizations(packageName)
测试 通过 ADB 测试 App Standby 可以强制为应用分配任何 bucket 并检查其行为。这对于依赖后台同步、通知或定期更新的应用至关重要。测试应在物理设备或具有 Android 9+ 的模拟器上进行。
要强制设置 bucket,使用命令 adb shell am set-standby-bucket [package] [bucket],其中 bucket 可以是:active、working_set、frequent 或 rare。要查看当前 bucket — adb shell am get-standby-bucket [package]。系统还允许通过命令 adb shell dumpsys usagestats 模拟应用长时间不活动。
# 为应用设置 Rare bucket
$ adb shell am set-standby-bucket com.example.app rare
# 查看当前 bucket
$ adb shell am get-standby-bucket com.example.app
# 将所有 bucket 重置为 Active
$ adb shell dumpsys usagestats clear
# 查看系统的所有 bucket
$ adb shell dumpsys usagestats
设置 Rare bucket 后检查:WorkManager 任务是否在 24 小时内执行,AlarmManager 是否触发,FCM 通知是否送达,Foreground Service 是否无限制地工作。具有 Expedited Work 策略的 WorkManager 即使在 Rare bucket 中也应立即执行,因为它使用 Foreground Service。普通的 WorkManager 任务将根据 bucket 被延迟。
开发能够抵御 App Standby 的应用需要对后台任务采取明智的方法。基本原则:不要假设应用始终处于 Active bucket。设计后台工作使其能够以 Frequent 和 Rare bucket 特有的延迟正常运行。
Expedited Work(WorkManager 2.7+)在后台启动 Foreground Service,使任务能够独立于 bucket 立即执行。这是适合不可延迟任务的最佳选择:发送消息、支付后同步、处理来电。普通的 WorkManager 任务在维护窗口中执行,考虑 bucket 因素。
使用 FCM high-priority 消息将应用从 App Standby 唤醒。当应用收到此类消息时,其 bucket 暂时提升为 Active,并可以执行必要的任务(同步、数据更新)。处理完成后,bucket 返回到原始级别。
不要尝试通过永久后台服务、WakeLock 或定期 FCM 消息绕过 App Standby。Google 积极打击此类做法——应用可能被标记为高耗能并受到更严格的限制。使用 WorkManager 处理定期任务,仅在任务真正对用户可见时使用 Foreground Service。
常见问题
App Standby 是一种 Android 机制,根据使用频率对应用进行分类,并限制不常用应用的后台活动。与 Doze 不同,App Standby 在应用级别工作,独立于屏幕状态和设备运动。
有 4 个级别:Active(无限制)、Working Set(最多延迟 2 小时)、Frequent(最多延迟 4 小时)和 Rare(最多延迟 24 小时)。级别根据应用使用频率自动确定。
App Standby 独立于设备状态限制特定不常用应用。Doze Mode 在设备闲置时限制所有应用(屏幕关闭、无运动)。它们并行工作,在 Android 节能系统中相互补充。
使用 ADB 命令:adb shell am get-standby-bucket [package]。以编程方式 — 通过 UsageStatsManager.getAppStandbyBucket(),从 Android 9(API 28)起可用。该方法返回 bucket 的数字标识符:10(Active)、20(Working Set)、30(Frequent)、40(Rare)。
使用 WorkManager Expedited Work 或带有通知的 Foreground Service。Expedited Work 在后台启动 Foreground Service 并保证独立于 bucket 执行。普通的 WorkManager 任务将根据应用的当前级别被延迟。
总结
adb shell am set-standby-bucket 检查每个级别的行为我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。