电池续航时间是用户体验的一个关键方面,而唤醒锁定在其中发挥着重要作用。您是否过度使用了唤醒锁定?在这篇博文中,我们将探讨唤醒锁定是什么、使用唤醒锁定的一些最佳实践,以及如何通过 Play 管理中心指标更好地了解您自己的应用的行为。
Android Vitals 中过度使用局部唤醒锁定
Play 管理中心现在会监控电池耗电量,并重点关注 过度使用局部唤醒锁定,将其作为关键性能指标。
此功能提升了电池效率的重要性,与现有的核心指标稳定性指标(用户感知到的崩溃和 ANR 过多)并列。我们 针对过度唤醒锁定定义了不良行为阈值。从 2026 年 3 月 1 日起,如果您的应用不符合此质量阈值,我们可能会将其从醒目的曝光途径(例如推荐)中排除。在某些情况下,我们可能会在您的商品详情中显示一条警告,向用户表明您的应用可能会导致电池耗电过多。
__Android Vitals 概览__中的过度唤醒锁定警告。.
对于移动设备,Android Vitals 指标适用于在屏幕关闭且应用在后台运行或运行前台服务时获取的非豁免唤醒锁定。如果出现以下情况,Android Vitals 会认为局部唤醒锁定使用过多:
- 在 24 小时内,唤醒锁定至少保持了 2 小时。
- 在 28 天内,唤醒锁定影响了应用超过 5% 的会话(平均值)。
由 音频、位置信息和 JobScheduler 用户发起的 API 创建的唤醒锁定不计入唤醒锁定计算。
了解唤醒锁定
唤醒锁定是一种机制,可让应用在用户未主动与设备交互时保持设备 CPU 运行。
局部唤醒锁定可让 CPU 即使在屏幕关闭时也能保持运行,防止 CPU 进入低功耗“暂停”状态。完全唤醒锁定可让屏幕和 CPU 都保持运行。
局部唤醒锁定可通过以下 2 种方法获取:
- 应用针对特定用例使用 PowerManager API 手动获取和释放唤醒锁定;通常,此唤醒锁定与 前台服务(一种旨在用于用户可感知操作的平台生命周期 API)一起获取。
- 或者,唤醒锁定由另一个 API 获取,并因使用该 API 而归因于应用;如需了解详情,请参阅最佳实践部分。
虽然唤醒锁定对于完成用户发起的大型文件下载等任务是必需的,但过度或不当使用唤醒锁定可能会导致电池耗电过多 。我们发现,有些应用会保持唤醒锁定数小时,或者无法正确释放唤醒锁定,导致用户抱怨即使在不与应用交互时,电池耗电量也会显著增加。
唤醒锁定使用最佳实践
在介绍如何调试过度使用唤醒锁定的问题之前,请确保您遵循了唤醒锁定最佳实践。
请考虑以下四个关键问题。
1. 您是否考虑过其他唤醒锁定选项?
在考虑获取手动局部唤醒锁定之前,请遵循以下决策流程图:
用于确定何时手动获取唤醒锁定的流程图
- 屏幕是否需要保持开启状态?
- 是:请改为参阅保持屏幕开启状态文档
- 应用是否正在运行前台服务?
- 否:您无需手动获取唤醒锁定。
- 如果设备暂停,是否会对用户体验造成不利影响?
- 否:例如,在设备唤醒后更新通知不需要唤醒锁定。
- 是:如果防止设备暂停至关重要(例如与外部设备进行持续通信),请继续。
- 是否有 API 已经代表您保持设备唤醒状态?
- 您可以利用识别由其他 API 创建的唤醒锁定文档来识别由其他 API 创建的唤醒锁定的场景,例如 LocationManager。
- 如果没有 API,请继续回答最后一个问题。
- 如果您已回答所有这些问题,并且确定没有其他替代方案,则应继续手动获取唤醒锁定。
**2. 您是否正确命名了唤醒锁定?
手动获取唤醒锁定时,正确的命名对于调试非常重要:
- 请勿在名称中包含任何个人身份信息 (PII),例如电子邮件地址。如果检测到 PII,唤醒锁定将记录为
_UNKNOWN,从而妨碍调试。 - 请勿使用类名或方法名称以编程方式命名唤醒锁定,因为这些名称可能会被 Proguard 等工具混淆。请改为使用硬编码字符串。
- 请勿向唤醒锁定标签添加计数器或唯一标识符。每次运行唤醒锁定时都应使用相同的标签,以便系统按名称汇总使用情况,从而更轻松地检测异常行为。
3. 获取的唤醒锁定是否始终会释放?
如果您是手动获取唤醒锁定,请确保始终执行唤醒锁定释放操作。未能释放唤醒锁定可能会导致电池耗电过多。
例如,如果在 processingWork() 期间抛出未捕获的异常,则可能永远不会发生 release() 调用。相反,您可以使用 try-finally 代码块来保证唤醒锁定会被释放,即使发生异常也是如此。
此外,您还可以为唤醒锁定添加超时时间,以确保它在特定时间段后释放,防止它被无限期地保持。
fun processingWork() {
wakeLock.apply {
try {
acquire(60 * 10 * 1000) // timeout after 10 minutes
doTheWork()
} finally {
release()
}
}
}4. 您可以降低唤醒频率吗?
对于定期数据请求,减少应用唤醒设备的频率是电池优化的关键。以下是一些降低唤醒频率的示例:
- WorkManager: 增加 PeriodicWorkRequests 中的定期间隔。
- SensorManager: 通过在注册监听器时指定 maxReportLatencyMs 来利用批处理。
- 一体化位置信息提供程序:
- 使用 getLastLocation 获取最近缓存的位置信息,以降低位置信息检索频率。
- 使用 setPriority(PRIORITY_PASSIVE) 采用耗电量较低的更新方法。
- 此外,您还可以通过使用 setMinUpdateIntervalMillis 设置最小更新间隔来利用位置信息批处理机制。
如需了解详情,请参阅唤醒锁定最佳实践文档。
调试过度使用唤醒锁定的问题
即使是出于好意,也可能会出现过度使用唤醒锁定的情况。如果您的应用在 Play 管理中心内被标记,请按以下步骤进行调试:
使用 Play 管理中心进行初步识别
Android Vitals 过度使用局部唤醒锁定信息中心提供了与您的应用关联的非豁免唤醒锁定名称的细分数据,显示了受影响的会话和时长。请注意,您可以使用文档来帮助您确定唤醒锁定名称是由应用保持还是由其他 API 保持。
Android Vitals 过度使用局部唤醒锁定信息中心向下滚动到细分数据部分,以查看过度使用的唤醒锁定标签。
调试工作器/作业保持的过度唤醒锁定
您可以使用以下唤醒锁定名称来识别工作器保持的唤醒锁定:
*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
如需查看工作器保持的唤醒锁定名称的完整变体列表,请参阅文档。如需调试这些唤醒锁定,您可以使用后台任务检查器在本地进行调试,也可以利用 getStopReason 在现场调试问题。
Android Studio 后台任务检查器
后台任务检查器的屏幕截图,其中能够识别出经常重试并失败的工作器“WeatherSyncWorker”。
如需在本地调试 WorkManager 问题,请在模拟器或已连接的设备(API 级别 26 及更高版本)上使用此工具。它会显示工作器及其状态(已完成、正在执行、已排队)的列表,让您可以检查详细信息并了解工作器链。
例如,它可以显示工作器是否因达到系统限制而经常失败或重试。
如需了解详情,请参阅后台任务检查器文档。
WorkManager getStopReason
如需在现场调试具有过度唤醒锁定的工作器,请在 WorkManager 2.9.0 及更高版本上使用 WorkInfo.getStopReason(),或对于 JobScheduler,请使用 SDK 31 及更高版本上提供的 JobParameters.getStopReason()。
此 API 可帮助记录工作器停止的原因(例如 STOP_REASON_TIMEOUT、STOP_REASON_QUOTA),从而找出问题,例如因运行时长耗尽而频繁超时。
backgroundScope.launch {
WorkManager.getInstance(context)
.getWorkInfoByIdFlow(workRequest.id)
.collect { workInfo ->
logStopReason(workRequest.id, workInfo?.stopReason)
}
}如需了解详情,请参阅针对任务调度 API 优化电池用量。
调试其他类型的过度唤醒锁定
对于涉及手动保持的唤醒锁定或保持唤醒锁定的 API 等更复杂的场景,我们建议您使用系统跟踪记录收集进行调试。
系统跟踪记录收集
系统跟踪记录 是一种强大的调试工具,可捕获一段时间内系统活动的详细记录,提供有关 CPU 状态、线程活动、网络活动以及与电池相关的指标(例如作业时长和唤醒锁定使用情况)的洞见。
您可以使用多种方法捕获系统跟踪记录:
- 利用系统跟踪记录命令行工具
- 使用 Android Studio CPU 性能分析器
- 使用 Perfetto 界面
- 直接从开发者选项在设备上手动记录跟踪记录 直接从开发者选项。
在 Perfetto 界面的“Android 应用和服务”标签页下启用“power:PowerManagement”Atrace 类别。
无论选择哪种方法,都必须确保收集 “power:PowerManagement”Atrace 类别 ,以便查看设备状态轨迹。
Perfetto 界面检查和 SQL 分析
您可以在 Perfetto 界面 中打开和检查系统跟踪记录。打开跟踪记录后,您将看到时间轴上各种进程的可视化效果。在本指南中,我们将重点介绍“设备状态”下的轨迹。
固定“设备状态”下的轨迹,例如“热门应用”“屏幕状态”“长时间唤醒锁定”和“作业”轨迹,以直观地识别长时间运行的唤醒锁定切片。
每个代码块都会列出事件的名称、事件的开始时间和结束时间。在 Perfetto 中,这称为切片。
如需对多个跟踪记录进行可扩缩分析,您可以使用 Perfetto 的 SQL 分析。SQL 查询可以找到按时长排序的所有唤醒锁定,帮助识别导致过度使用的主要因素。
以下是一个示例查询,用于汇总系统跟踪记录中发生的所有唤醒锁定标签,并按总时长排序:
SELECT slice.name as name, track.name as track_name,SUM(dur / 100000) as total_dur_ms FROM slice JOIN track ON slice.track_id = track.id WHERE track.name = 'WakeLocks'GROUP BY slice.name, track.name ORDER BY total_dur_ms DESC
使用 ProfilingManager 进行现场跟踪记录收集
对于难以重现的问题,ProfilingManager(在 SDK 35 中添加)是一个程序化 API,允许开发者使用开始和结束触发器在现场收集系统跟踪记录。它可以更好地控制配置文件收集的开始和结束触发点,并强制执行系统级速率限制,以防止影响设备性能。
如需了解有关如何在现场实现系统跟踪记录收集的更多步骤,请查看 ProfilingManager 文档,其中包括如何以编程方式 捕获跟踪记录、分析分析数据 以及使用 本地调试命令。
使用 ProfilingManager 收集的系统跟踪记录与手动收集的跟踪记录类似,但系统进程和其他应用进程会从跟踪记录中删除。
总结
Android Vitals 中的过度使用局部唤醒锁定指标只是我们持续致力于帮助开发者减少电池耗电量和提高应用质量的一小部分。
通过了解和正确实现唤醒锁定,您可以显著优化应用的电池性能。利用替代 API、遵循唤醒锁定最佳实践以及使用强大的调试工具(例如后台任务检查器、系统跟踪记录和 ProfilingManager)是确保您的应用在 Google Play 上取得成功的关键。
-
Product NewsToday, we officially celebrate five years since the release of Jetpack Compose 1.0. From version 1.0, announced on July 28th, 2021, to our latest 1.11 release, we’ve seen the APIs evolve significantly over the years, and we’re taking a moment to celebrate.
Rebecca Franks, Nick Butcher, Loryn Hairston • 5 min read -
Product NewsAndroid Studio Quail 2 is now stable and ready for you to use in production, bringing a shift to your IDE with concurrent agentic workflows, natively integrated memory leak profiling, and context-aware crash remediation.
Amman Asfaw • 3 min read -
Product NewsBack in March, we introduced Android Bench—our LLM leaderboard for real-world Android development tasks. Since then, we have enhanced the benchmark based on your feedback, including evaluating open-weight models and adding cost and efficiency dimensions to the leaderboard.
Zoe Lopez-Latorre • 3 min read
Get the latest Android development insights delivered to your inbox weekly.