电池续航时间是用户体验的一个关键方面,而唤醒锁定在其中起着重要作用。您是否过度使用了这些 API?在这篇博文中,我们将探讨什么是唤醒锁定、使用唤醒锁定的一些最佳实践,以及如何通过 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:增加 PeriodicWorkRequest 中的周期性间隔。
- 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(),或在 SDK 31 及更高版本中使用 JobScheduler 的 JobParameters.getStopReason()。
此 API 有助于记录 worker 停止的原因(例如 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 apps & svcs”标签页下,启用“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 上取得成功的关键。
-
产品资讯随着智能体开发不断加速,Android 工程领域正迈向一个令人振奋的新境界:从辅助性代码补全,跃升至智能体在您的指挥下执行端到端任务。您可以完全自主、灵活地选择要使用的模型和智能体。
Jason Buchel • 阅读用时:3 分钟 -
产品资讯今天,我们分享了如何将“不只是商店”的愿景推进到下一个阶段。从月活跃用户数超过 2.5 亿的“我”标签页,到连接超过 7 亿玩家资料的统一游戏平台,Google Play 始终致力于满足用户的各种需求。
Paul Feng • 阅读用时:3 分钟 -
产品资讯我们很高兴能通过 Googlebook 帮助用户表达自我,并让他们能够使用这些工具。
Cyrus Stoller • 阅读用时:2 分钟
每周通过电子邮件接收最新的 Android 开发洞见。