Doze Mode是Android 6.0 Marshmallow中引入的一种省电模式,在设备闲置时显著限制应用程序的后台活动。系统将应用程序切换到低功耗状态,延迟网络请求、同步和JobScheduler,以延长电池续航时间。根据Android Developers, 2025的分析,Doze Mode可以将设备的待机时间延长2–3倍,具体取决于型号和操作系统版本。
要点
Doze Mode是Android内置的节能机制,当设备未连接充电器、屏幕关闭且用户在特定时间内未与设备交互时激活。Doze的目标是最小化应用程序的后台活动,以最大化待机模式下的电池续航时间。系统会延迟JobScheduler、账户同步、AlarmManager和网络请求。
该模式在Android 6.0 Marshmallow(API 23)中引入,并在后续版本中得到了显著改进。在Android 7.0 Nougat中出现了第二阶段(Light Doze),在设备移动时激活。Android 8.0对与Doze配合使用的后台服务引入了额外限制。在Android 12+中,Doze与更新的电池管理系统集成,分析用户行为。
理解这一点很重要:Doze Mode不会完全禁用应用程序。它会将应用程序切换到具有延迟任务的状态,但不会终止进程。带有通知的Foreground Service继续运行,高优先级推送通知(FCM high-priority)会被送达,闹钟按计划触发。Doze仅影响用户当前看不到且不期望的后台操作。
Doze Mode在满足所有条件时激活:屏幕关闭超过30分钟(首次激活),设备静止(使用加速度计),未连接充电器。如果用户拿起手机或连接充电器,Doze立即停用。在Android 7+中,Light Doze在闲置5分钟后即可激活,即使设备在移动中。
Doze Mode通过系统服务DeviceIdleController管理后台活动,该服务分析传感器、屏幕和充电器的状态。当所有激活条件满足时,系统将应用程序切换到待机模式,将其请求分组到服务窗口中。在这些窗口内,所有延迟的任务——网络调用、同步、AlarmManager——批量执行。
系统PowerManager控制哪些应用程序可以从Doze中退出。高优先级推送通知(FCM high-priority)可以唤醒设备以传递消息。系统还会忽略用户添加到电池优化Whitelist中的应用程序的Doze。所有其他应用程序必须等待下一个服务窗口。
Deep Doze中服务窗口的持续时间呈指数级增长:第一个窗口在1小时后,第二个在2小时后,第三个在4小时后,依此类推,直到最大12小时间隔。这意味着设备在Doze中停留的时间越长,应用程序执行后台任务的频率就越低——电池被最大程度地节约。
在Doze Mode中,所有网络请求都会暂停,直到服务窗口到来。只有FCM high-priority消息(payload中带有“high_priority”标签)和来自AlarmManager带有setAndAllowWhileIdle()或setExactAndAllowWhileIdle()标志的信号为例外。通过Retrofit、OkHttp或Volley的常规网络调用在窗口打开之前不会执行。
Doze Mode由两个阶段组成:Light Doze(轻度睡眠)和Deep Doze(深度睡眠)。每个阶段都施加自己的限制,并具有不同的激活阈值。理解阶段之间的差异对于设计能够抵抗省电模式的后台任务的开发人员至关重要。
Light Doze在设备闲置5–30分钟后激活(屏幕关闭,无移动)。在此阶段,网络请求和同步暂停,但AlarmManager和JobScheduler继续以较小的延迟工作。应用程序在收到推送通知或连接充电器时可以从Light Doze中退出。Light Doze不需要完全静止——设备可以移动。
Deep Doze在设备静止(加速度计未检测到移动)且闲置60–90分钟后发生。在Deep Doze中,系统更积极地延迟任务:服务窗口打开频率降低(间隔呈指数增长),AlarmManager仅通过setAndAllowWhileIdle()标志触发,WakeLock在正常模式下不工作。不在Whitelist中的应用程序几乎完全失去后台活动。
| 参数 | Light Doze | Deep Doze |
|---|---|---|
| 激活时间 | 5–30分钟 | 60–90分钟 |
| 移动要求 | 不需要 | 静止 |
| 窗口间隔 | 10–60分钟 | 1–12小时 |
| AlarmManager | 延迟工作 | 仅withAllowWhileIdle |
| 窗口中的网络 | 可用 | 可用 |
Doze Mode施加了几类限制,开发人员在设计应用程序时必须考虑。忽视这些限制会导致后台任务无法执行,用户看到应用程序运行不正确——缺少更新、消息未发送、同步未完成。
所有网络请求在服务窗口到来之前被阻塞。这包括HTTP调用、WebSocket连接、文件下载。例外——FCM high-priority消息,它们通过独立的Google Play Services通道传输,不依赖于Doze。对于关键数据的同步,建议使用具有NetworkType.CONNECTED策略的WorkManager。
Deep Doze中的AlarmManager会延迟所有闹钟,除了通过setAndAllowWhileIdle()
setExactAndAllowWhileIdle()方法创建的闹钟。然而,即使这些方法也有限制——每个应用每9分钟不超过1次触发。Deep Doze中的精确闹钟setExact()不保证在指定时间触发。
WakeLock在Doze Mode中非标准地工作:系统不为Whitelist之外的应用程序保持睡眠锁定。即使应用程序正确获取了PARTIAL_WAKE_LOCK,在Deep Doze到来时系统也可以强制释放它。保证在Doze中执行任务的唯一方法是使用带有通知的Foreground Service。
Whitelist(白名单)Doze是系统允许在省电模式下以最小限制进行后台活动的应用程序集合。用户可以通过设置 → 电池 → 电池优化手动添加应用程序。系统应用程序、启动器和Google Play Services默认在Whitelist中。
开发人员可以通过带有Intent ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS的系统对话框请求添加到Whitelist。这需要在清单中拥有REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限。然而,Google不建议无故请求例外——滥用此功能的应用程序在Google Play发布时面临被拒绝的风险。
没有Whitelist,应用程序可以使用FCM high-priority将设备从Doze中唤醒。每个这样的消息都会给应用程序一个短暂的时间窗口(10–30秒)来执行任务。对于更长的操作,应用程序必须启动Foreground Service,它将在Doze的服务窗口中继续工作。Google还为某些类型的应用程序提供了豁免机制:导航、医疗、通讯应用。
要检查应用程序是否在电池优化的Whitelist中,使用powerManager.isIgnoringBatteryOptimizations()方法。如果方法返回false,则应用程序受所有Doze限制的约束。如果返回true——应用程序即使是在Deep Doze中也可以无限制地使用Wakelock、AlarmManager和网络。然而,滥用此特权会导致用户差评。
测试应用程序在Doze Mode中的行为是开发的强制阶段,因为Doze可能会干扰后台功能。Android通过ADB提供命令行工具,用于强制将设备切换到Light Doze和Deep Doze。测试必须在物理设备或Android 6.0+模拟器上进行。
进入Light Doze使用命令adb shell dumpsys deviceidle step light。进入Deep Doze——adb shell dumpsys deviceidle step deep。命令adb shell dumpsys deviceidle force-idle deep立即将设备切换到Deep Doze,无需等待标准超时。测试后,使用命令adb shell dumpsys deviceidle unforce关闭Doze。
# 强制进入Light Doze
$ adb shell dumpsys deviceidle step light
# 强制进入Deep Doze
$ adb shell dumpsys deviceidle step deep
# 立即转换到Deep Doze
$ adb shell dumpsys deviceidle force-idle deep
# 退出Doze
$ adb shell dumpsys deviceidle unforce
# 查看Doze状态
$ adb shell dumpsys deviceidle
切换到Doze Mode后,需要检查:网络请求是否工作(应被延迟),AlarmManager是否触发,FCM消息是否送达,WorkManager任务是否正确执行。WorkManager在Doze中继续工作:其任务在服务窗口中执行。但是,如果任务需要立即执行,必须指定setExpedited()或使用Foreground Service。
开发能够抵抗Doze Mode的应用程序需要重新思考后台任务的方法。Google建议设计应用程序使其在任何Doze限制下都能正常工作,而不依赖于后台操作的立即执行。基本原则——对所有可以延迟的后台任务使用WorkManager。
WorkManager是Google推荐用于后台任务的API,因为它会自动适应Doze。WorkManager使用JobScheduler(API 23+)或旧版本上的AlarmManager + BroadcastReceiver。WorkManager任务在最近的Doze服务窗口中执行,必要时——通过Expedited Work(幕后的Foreground Service)立即执行。
如果任务不能延迟(媒体播放、导航、VoIP),请使用带有强制通知的Foreground Service。Foreground Service从Doze中获得豁免:它可以保持WakeLock并执行网络请求。然而,即使是Foreground Service也受到Deep Doze服务窗口策略的约束——例如dataSync。
为了传递需要立即关注的消息(来电、紧急通知),使用FCM high-priority消息。此类消息将设备从Doze中唤醒,并为应用程序提供短暂的处理窗口。不要对常规通知使用high-priority——这会导致电池快速耗尽,并可能被Google Play视为违反政策。
常见问题
Doze Mode是Android 6+的一种省电模式,当设备未使用(屏幕关闭,无移动)时限制应用程序的后台活动。系统延迟网络请求、同步和JobScheduler,将它们分组到服务窗口中以节省电池。
Doze Mode有两个阶段:Light Doze(轻度睡眠)在5–30分钟后激活,允许AlarmManager以延迟方式工作。Deep Doze(深度睡眠)在60–90分钟静止后发生,通过长达12小时的服务窗口积极限制后台任务。
Doze阻止网络请求,延迟AlarmManager(除了setAndAllowWhileIdle),强制释放WakeLock并将JobScheduler分组到服务窗口中。例外——Foreground Service、FCM high-priority和用户的Whitelist应用程序。
在清单中请求REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限,并使用操作ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS发送Intent。系统将向用户显示对话框。添加到Whitelist是一种特权,Google建议仅关键应用程序使用。
使用ADB命令:adb shell dumpsys deviceidle force-idle deep进入Deep Doze,adb shell dumpsys deviceidle step light进入Light Doze,adb shell dumpsys deviceidle unforce退出。在每个模式下检查WorkManager、AlarmManager和FCM的工作情况。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。