优化 Doze 和应用待机

Android 具有两种省电功能,通过管理应用在设备未连接电源时的行为来延长用户的电池续航时间:Doze 和应用待机。Doze 通过延迟应用在设备长时间未使用时的后台 CPU 和网络活动来降低功耗。应用待机 延迟了最近没有用户活动的应用的后台网络活动。

当设备处于 Doze 模式时,应用访问某些耗电资源的权限会被延迟,直到维护窗口开启。具体限制列在 电源管理限制 中。

Doze 和应用待机管理着所有在 Android 6.0 或更高版本上运行的应用的行为,无论它们是否专门针对 API 级别 23。为了帮助确保为用户提供最佳体验,请在 Doze 和应用待机模式下测试您的应用,并对代码进行必要的调整。以下部分提供详细信息。

了解 Doze

如果用户将设备断开电源并静置一段时间,且屏幕关闭,则设备会进入 Doze 模式。在 Doze 模式下,系统会尝试通过限制应用访问网络和 CPU 密集型服务来节省电池电量。它还会阻止应用访问网络,并延迟其作业、同步和标准闹钟。

系统会定期退出 Doze 一段时间,以让应用完成其延迟的活动。在此维护窗口期间,系统会运行所有挂起的同步、作业和闹钟,并允许应用访问网络。

图 1. Doze 为应用提供定期维护窗口,以便它们使用网络和处理挂起的活动。

维护窗口结束后,系统会再次进入 Doze,暂停网络访问并延迟作业、同步和闹钟。随着时间的推移,系统会减少维护窗口的调度频率,从而帮助在设备未充电且长时间不活动的情况下减少功耗。

当用户通过移动设备、打开屏幕或连接充电器唤醒设备时,系统会退出 Doze,所有应用恢复正常活动。

Doze 限制

系统在 Doze 模式下会对您的应用应用以下限制

Doze 检查清单

使您的应用适应 Doze 模式

Doze 会以不同的方式影响应用,具体取决于它们提供的功能和使用的服务。许多应用在 Doze 周期中无需修改即可正常运行。在某些情况下,您必须优化应用管理网络、闹钟、作业和同步的方式。应用必须能够在每个维护窗口期间有效地管理活动。

为了帮助安排闹钟,您可以使用两种 AlarmManager 方法:setAndAllowWhileIdle()setExactAndAllowWhileIdle()。使用这些方法,您可以设置即使设备处于 Doze 模式也能触发的闹钟。

Doze 对网络访问的限制也可能影响您的应用,尤其是在应用依赖于实时消息(如轻触或通知)的情况下。如果您的应用需要持续连接到网络才能接收消息,请尽可能使用 Firebase Cloud Messaging (FCM)

要确认您的应用在 Doze 模式下的行为是否符合预期,您可以使用 adb 命令强制系统进入和退出 Doze 模式,并观察应用的行为。有关详细信息,请参阅 在 Doze 和应用待机模式下进行测试

了解应用待机模式

当用户未积极使用应用时,应用待机模式允许系统确定该应用处于空闲状态。当用户在一段时间内未触碰应用并且不满足以下任何条件时,系统会做出此判断

  • 用户显式启动应用。
  • 应用当前有一个进程位于前台,无论是作为活动还是前台服务,或者正被其他活动或前台服务使用。
  • 应用生成用户在锁定屏幕或通知栏上看到的通知。

当用户将设备插入电源时,系统会将应用从待机状态释放,从而允许它们自由访问网络并执行任何挂起的作业和同步。如果设备长时间处于空闲状态,系统大约每天会允许空闲应用访问网络一次。

使用 FCM 在设备空闲时与您的应用交互

Firebase Cloud Messaging (FCM) 是一种云到设备服务,可让您支持后端服务与 Android 设备上的应用之间的实时下行消息传递。FCM 提供与云的单一、持久连接。所有需要实时消息传递的应用都可以共享此连接。此共享连接通过使多个应用无需维护自己的独立持久连接(这会导致电池快速耗尽)来显着优化电池消耗。因此,如果您的应用需要与后端服务集成消息传递,我们强烈建议您尽可能使用 FCM,而不是维护自己的持久网络连接。

FCM 已针对 Doze 和应用待机空闲模式进行了优化。FCM 高优先级消息允许您唤醒应用以与用户互动。在 Doze 或应用待机模式下,系统会传递消息并允许应用临时访问网络服务和部分唤醒锁,然后将设备或应用返回到空闲状态。对于时间敏感的用户可见通知,请考虑使用高优先级消息以在 Doze 模式下启用传递。高优先级消息可能导致通知。有关更多信息,请参阅 FCM 关于高优先级消息的指南

对于不会导致通知的消息(例如在后台保持应用内容最新或启动数据同步),请使用普通优先级 FCM 消息。如果设备未处于 Doze 模式,则会立即传递普通优先级消息。如果设备处于 Doze 模式,则会在定期 Doze 维护窗口或用户唤醒设备后立即传递。

作为一般最佳实践,如果您的应用需要下行消息传递,请使用 FCM。如果您的应用已使用 FCM,请确保它仅对导致用户界面通知的消息使用高优先级消息。

对其他用例的支持

几乎所有应用都能够通过管理网络连接、闹钟、作业和同步以及使用 FCM 消息来支持 Doze。对于一小部分用例,这可能是不够的。对于此类情况,系统提供了一个可配置的应用列表,这些应用部分免于 Doze 和应用待机优化。

部分免于优化的应用可以在 Doze 和应用待机期间使用网络并保持 部分唤醒锁。但是,其他限制仍然适用于该应用,就像适用于其他应用一样。例如,应用的作业和同步在 API 级别 23 及以下版本中被延迟,并且其常规 AlarmManager 闹钟不会触发。应用可以通过调用 isIgnoringBatteryOptimizations() 来检查它当前是否在豁免列表中。

用户可以在“**设置 > 电池 > 电池优化**”中手动配置豁免应用列表。或者,系统提供了一种方法供应用要求用户将其豁免

应用可以通过调用 isIgnoringBatteryOptimizations() 来检查它当前是否在豁免列表中。

在 Doze 和应用待机模式下进行测试

为了帮助确保为您的用户提供良好的体验,请在 Doze 和应用待机模式下全面测试您的应用。

在 Doze 模式下测试您的应用

您可以通过执行以下操作来测试 Doze 模式

  1. 使用 Android 6.0(API 级别 23)或更高版本的系统映像配置硬件设备或虚拟设备。
  2. 将设备连接到您的开发机器并安装您的应用。
  3. 运行您的应用并保持其处于活动状态。
  4. 通过运行以下命令强制系统进入空闲模式
        $ adb shell dumpsys deviceidle force-idle
        
  5. 准备就绪后,通过运行以下命令退出空闲模式
        $ adb shell dumpsys deviceidle unforce
        
  6. 通过执行以下命令重新激活设备
        $ adb shell dumpsys battery reset
        
  7. 在重新激活设备后观察应用的行为。确保应用在设备退出 Doze 模式时能够优雅地恢复。

在应用待机模式下测试您的应用

要使用您的应用测试应用待机模式,请执行以下操作

  1. 使用 Android 6.0(API 级别 23)或更高版本的系统映像配置硬件设备或虚拟设备。
  2. 将设备连接到您的开发机器并安装您的应用。
  3. 运行您的应用并保持其处于活动状态。
  4. 通过运行以下命令强制应用进入应用待机模式
        $ adb shell dumpsys battery unplug
        $ adb shell am set-inactive <packageName> true
        
  5. 使用以下命令模拟唤醒您的应用
        $ adb shell am set-inactive <packageName> false
        $ adb shell am get-inactive <packageName>
        
  6. 在唤醒应用后观察其行为。确保应用能够从待机模式优雅地恢复。尤其要检查应用的通知和后台作业是否按预期工作。

豁免的可接受用例

下表突出显示了一些用例,以及在这些情况下应用是否可以使用 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 意图操作。通常,除非 Doze 或应用待机破坏了应用的核心功能,或者存在您的应用无法使用 FCM 高优先级消息的技术原因,否则您的应用不符合这些例外情况。

有关更多信息,请参阅 对其他用例的支持

类型 用例 可以使用 FCM 吗? 豁免是否可接受? 备注
即时消息、聊天或呼叫应用。 需要在设备处于 Doze 模式或应用处于应用待机模式时向用户传递实时消息。 是,使用 FCM 不可接受 使用 FCM 高优先级消息唤醒应用并访问网络。
是,但未使用 FCM 高优先级消息。
即时消息、聊天或呼叫应用;企业 VOIP 应用。 否,由于技术依赖于其他消息传递服务或 Doze 和应用待机破坏了应用的核心功能,因此无法使用 FCM。 可接受
安全应用。 保护用户及其家人安全的应用。 如果适用。 可接受
任务自动化应用。 应用的核心功能是安排自动化操作,例如即时消息、语音通话或新的照片管理。 如果适用。 可接受
外围设备配套应用。 应用的核心功能是与外围设备保持持久连接,以便为外围设备提供互联网访问。 如果适用。 可接受
应用只需要定期连接到外围设备进行同步,或者只需要连接到通过标准蓝牙配置文件连接的设备(例如无线耳机)。 如果适用。 不可接受