为可穿戴设备构建 Android 应用意味着,当屏幕关闭时,真正的工作才刚刚开始。WHOOP 可帮助会员了解自己的身体对训练、恢复、睡眠和压力的反应,对于许多使用 Android 设备的 WHOOP 会员来说,可靠的后台同步和连接是获得这些洞见的基础。
今年早些时候,Google Play 在 Android Vitals 中发布了一项新指标:过度使用部分唤醒锁定。此指标用于衡量在 24 小时内,累积的非豁免唤醒锁定使用时间超过 2 小时的用户会话所占的百分比。此指标旨在帮助您识别和解决可能导致耗电过快的问题,这对于提供出色的用户体验至关重要。
自 2026 年 3 月 1 日起,如果应用继续不符合质量阈值,可能会被排除在 Google Play 发现界面之外。此外,Google Play 商店商品详情中可能会显示警告,指出该应用可能会比预期消耗更多电量。
据 WHOOP 的高级 Android 工程师 Mayank Saini 称,Android Vitals 将该应用的过度使用部分唤醒锁定百分比标记为 15%(超过了建议的 5% 阈值)后,这“为团队提供了一个提高 Android 效率的机会”。
该团队将 Android Vitals 指标视为一个明确的信号,表明他们的后台工作使 CPU 保持唤醒状态的时间过长。解决此问题后,他们便可以继续提供出色的用户体验,同时减少浪费的后台时间,并保持可靠且及时的蓝牙连接和同步。
找出问题
为了确定从何处入手,该团队首先查看了 Android Vitals,以更深入地了解哪些唤醒锁定影响了该指标。通过查阅 Android Vitals 过度使用部分唤醒锁定信息中心,他们能够确定导致过度使用部分唤醒锁定的最大因素是他们的一个 WorkManager worker(在信息中心内标识为 androidx.work.impl.background.systemjob.SystemJobService)。为了支持 WHOOP 的“始终开启体验”,该应用使用 WorkManager 执行后台任务,例如定期同步和向可穿戴设备提供定期更新。
虽然该团队 知道 WorkManager 在后台执行任务时会获取唤醒锁定,但他们之前无法了解所有后台工作(不仅仅是 WorkManager)的分布情况,直到 Android Vitals 中引入了过度使用部分唤醒锁定指标。
由于信息中心将 WorkManager 标识为主要因素,因此该团队能够专注于确定 哪些 worker 的贡献最大,并努力解决该问题。
利用内部指标和数据更好地缩小原因范围
WHOOP 已经设置了内部基础架构来监控 WorkManager 指标。他们会定期监控:
- 平均运行时长:worker 的运行时间有多长?
- 超时:worker 超时而不是完成的频率有多高?
- 重试:如果工作超时或失败,worker 重试的频率有多高?
- 取消:工作被取消的频率有多高?
除了跟踪 worker 的成功和失败情况之外,该团队还可以了解其工作的效率。
内部指标标记了少数几个 worker 的平均运行时长过高 ,这使他们能够进一步缩小调查范围。
除了内部指标之外,该团队还使用了 Android Studio 的 后台任务检查器 来检查和调试感兴趣的 worker,并特别关注关联的唤醒锁定,以与 Android Vitals 中标记的指标保持一致。
调查:区分 worker 变体
WHOOP 对某些 worker 使用 一次性调度和 定期调度。这样,应用就可以对具有相同成功条件且仅在时间上不同的相同任务重复使用相同的 worker 逻辑。
使用内部指标可以缩小搜索范围,找到特定的 worker,但他们无法确定 bug 是在 worker 一次性运行、定期运行还是两者都运行时发生的。因此,他们推出了更新,使用 WorkManager 的 setTraceTag 方法 来区分同一 worker 的一次性变体和定期变体。
通过这些额外详细信息,他们可以明确确定哪个 worker 变体(定期或一次性)对过度使用部分唤醒锁定的会话贡献最大。不过,当数据表明这两个变体似乎都没有比另一个变体贡献更多时,该团队感到很惊讶。
WHOOP 的 Android 工程师 II Manmeet Tuteja 表示:“这种拆分还有助于我们确认问题发生在 这两个变体中,这表明问题不是出在调度配置上,而是出在 worker 实现中的共享业务逻辑问题上。”
深入了解 worker 行为并解决根本原因
该团队知道需要查看 worker 内的逻辑,因此重新检查了调查期间标记的 worker 的 worker 行为。具体来说,他们寻找的是工作可能卡住且未完成的实例。
所有这些最终都找到了过度使用唤醒锁定的根本原因:
CoroutineWorker 旨在等待与 WHOOP 传感器建立连接,然后再继续。
如果工作开始时没有连接传感器,则 whoopSensorFlow(用于指示传感器是否已连接)为 null。SensorWorker 不会将此视为提前退出的条件,而是继续运行,实际上是无限期地等待连接。因此,WorkManager 会保留部分唤醒锁定,直到工作超时,从而导致后台唤醒锁定使用率过高,并频繁地不必要地重新安排 SensorWorker。
为了解决此问题,WHOOP 团队更新了 worker 逻辑,以便在尝试执行核心业务逻辑之前检查连接状态。
如果传感器不可用,worker 会退出,从而避免超时情况并释放唤醒锁定。以下代码段展示了解决方案:
class SensorWorker(appContext: Context, params: WorkerParameters): CoroutineWorker(appContext, params) { override suspend fun doWork(): Result { ... // Check the sensor state and perform work or return failure return whoopSensorFlow.replayCache .firstOrNull() ?.let { cachedData -> processSensorData(cachedData) Result.success() } ?: run { Result.failure() } }
过度使用部分唤醒锁定的会话数减少了 90%
推出修复程序后,该团队继续监控 Android Vitals 信息中心,以确认更改的影响。
最终,在对 worker 进行更改后仅 30 天,WHOOP 的过度使用部分唤醒锁定百分比就从 15% 降至不到 1% 。
由于这些更改,该团队发现工作超时但未完成的实例减少了,从而导致平均运行时长缩短。
WHOOP 团队向其他想要提高后台工作效率的开发者提出的建议:
开始使用
如果您有兴趣尝试减少应用的过度使用部分唤醒锁定,或尝试提高 worker 效率,请在 Android Vitals 中查看应用的过度使用部分唤醒锁定指标,并查看 唤醒锁定文档,了解更多最佳实践和调试策略。
继续阅读
-
案例研究
Monzo 是一家英国数字银行,拥有 1500 万客户,并且客户数量还在不断增长。随着应用规模的扩大,工程团队发现应用启动时间是一个需要改进的关键领域,但担心这需要对代码库进行重大更改。
Ben Weiss • 阅读时间:2 分钟
-
月 13 日月 13 日
案例研究
TikTok 是一个全球性的短视频平台,以其庞大的用户群和创新功能而闻名。
Ben Trengrove, Ajesh Pai • 阅读时间:2 分钟
-
案例研究
在瞬息万变的社交媒体世界中,用户注意力很快就会被吸引或失去。Meta 应用(Facebook 和 Instagram)是全球最大的社交平台之一,为全球数十亿用户提供服务。
Mayuri Khinvasara Khabya • 阅读时间:4 分钟
随时了解最新动态
每周通过电子邮件接收最新的 Android 开发洞见 每周。