事例紹介

WHOOP が過度の部分的な wake lock セッションを 90% 以上削減した方法

所要時間: 4 分

ウェアラブル向けの Android アプリを構築するということは、画面がオフになったときに実際の作業が始まることを意味します。WHOOP は、トレーニング、リカバリー、睡眠、ストレスに対する身体の反応をメンバーが理解できるようにサポートしています。Android を利用している多くの WHOOP メンバーにとって、信頼性の高いバックグラウンド同期と接続性が、そうした分析情報を可能にしています。

今年、Google Play は Android Vitals に新しい指標「過剰な部分的なウェイクロック」をリリースしました。この指標は、24 時間の期間内で、累積の非免除 wake lock の使用時間が 2 時間を超えたユーザー セッションの割合を測定します。この指標の目的は、バッテリーの消耗の原因を特定して対処できるようにすることです。これは、優れたユーザー エクスペリエンスを提供するために不可欠です。

2026 年 3 月 1 日以降、品質のしきい値を満たしていないアプリは、Google Play の検索結果に表示されなくなる可能性があります。また、Google Play ストアの掲載情報に警告が表示され、アプリのバッテリー使用量が想定より多い可能性があることが示されることもあります。

WHOOP のシニア Android エンジニアである Mayank Saini 氏によると、Android Vitals でアプリの過度の部分的な wake lock の割合が 15%(推奨の 5% のしきい値を超過)と報告された後、「チームは Android の効率性を高める機会を得ました」。

mayank.png

チームは、Android Vitals の指標を、バックグラウンド作業が CPU を必要以上に長く起動させていることを示す明確なシグナルと捉えました。この問題を解決することで、優れたユーザー エクスペリエンスを提供し続けながら、バックグラウンドでの無駄な時間を減らし、信頼性の高いタイムリーな Bluetooth 接続と同期を維持できるようになります。

問題を特定する

チームは、まず Android Vitals を確認して、どのウェイクロックが指標に影響しているかについての分析情報を取得しました。Android Vitals の過度の部分的な wake lock ダッシュボードを参照した結果、過度の部分的な wake lock の最大の原因は、WorkManager ワーカーの 1 つ(ダッシュボードでは androidx.work.impl.background.systemjob.SystemJobService として特定)であることがわかりました。WHOOP の「常時オン エクスペリエンス」をサポートするため、このアプリでは、定期的な同期やウェアラブルへの定期的な更新の配信などのバックグラウンド タスクに WorkManager を使用しています。

チームは、バックグラウンドでタスクを実行する際に WorkManager が wake lock を取得することを認識していましたが、Android Vitals に過剰な部分 wake lock の指標が導入されるまで、WorkManager 以外のすべてのバックグラウンド処理がどのように分散されているかを把握していませんでした。

ダッシュボードで WorkManager が主な原因であることが特定されたため、チームはどのワーカーが最も貢献しているかを特定し、問題の解決に向けて取り組むことに集中できました。

内部の指標とデータを使用して原因を特定する

WHOOP には、WorkManager の指標をモニタリングするための内部インフラストラクチャがすでに設定されていました。定期的にモニタリングする内容は次のとおりです。

  1. 平均実行時間: ワーカーの実行時間。
  2. タイムアウト: ワーカーが完了せずにタイムアウトする頻度。
  3. 再試行: 作業がタイムアウトまたは失敗した場合、ワーカーはどのくらいの頻度で再試行しますか?
  4. キャンセル: 作業は何回キャンセルされましたか?

ワーカーの成功と失敗だけでなく、それ以外の要素も追跡することで、チームは作業の効率性を把握できます。

内部指標で、一部のワーカーの平均実行時間が長いことが示されたため、調査範囲をさらに絞り込むことができました。

チームは、内部指標に加えて、Android Studio の Background Task Inspector を使用して、関連するウェイクロックに特に注目しながら、対象のワーカーを検査してデバッグし、Android Vitals でフラグが立てられた指標と照合しました。

調査: ワーカー バリエーションの区別

WHOOP は、一部のワーカーに 1 回限りのスケジューリングと定期的なスケジューリングの両方を使用します。これにより、アプリは、タイミングのみが異なる同じ成功条件の同一タスクに対して、同じ Worker ロジックを再利用できます。

内部指標を使用することで、検索を特定のワーカーに絞り込むことはできましたが、バグがワーカーの 1 回限りの実行時、定期的な実行時、またはその両方で発生したかどうかを判断することはできませんでした。そこで、WorkManager の setTraceTag メソッドを使用して、同じ Worker の 1 回限りのバリエーションと定期的なバリエーションを区別する更新をロールアウトしました。

この詳細情報があれば、過剰な部分的なウェイクロックが発生しているセッションに最も影響している Worker バリアント(定期的なものか 1 回限りのものか)を特定できます。しかし、データからどちらのバリエーションも他方より貢献しているようには見えないことが明らかになり、チームは驚きました。

WHOOP の Android エンジニア II である Manmeet Tuteja 氏は、「この分割により、問題が両方のバリエーションで発生していることを確認できました。これにより、スケジューリング構成ではなく、ワーカー実装内の共有ビジネス ロジックの問題に注目することができました」と述べています。

manmeet.png

ワーカーの動作を深く掘り下げ、根本原因を修正する

チームは、ワーカー内のロジックを確認する必要があることを認識し、調査中にフラグが立てられたワーカーのワーカーの動作を再調査しました。具体的には、作業が停止して完了していない可能性があるインスタンスを探していました。

この結果、過度の wake lock の根本原因が特定されました。

WHOOP センサーへの接続を待ってから処理を進めるように設計された CoroutineWorker。 

センサーが接続されていない状態で作業が開始された場合、センサーが接続されているかどうかを示す whoopSensorFlownull でした。SensorWorker はこれを早期終了条件として扱わず、実行を継続したため、接続を無期限に待機することになりました。その結果、WorkManager は処理がタイムアウトするまで部分的な wake lock を保持し、バックグラウンド wake lock の使用量が増加し、SensorWorker の不要な再スケジュールが頻繁に発生しました。

これに対処するため、WHOOP チームは、コア ビジネス ロジックの実行を試みる前に接続ステータスを確認するよう、ワーカー ロジックを更新しました。

センサーが利用できない場合、Worker は終了し、タイムアウト シナリオを回避して wake lock を解放します。次のコード スニペットは、解決策を示しています。

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()
            }
}

過度の部分的な wake lock があるセッションを 90% 削減

修正をリリースした後も、開発チームは Android Vitals ダッシュボードを継続的にモニタリングし、変更の影響を確認しました。

最終的に、WHOOP は Worker の変更を実装してからわずか 30 日で、過剰な部分的な wake lock の割合を 15% から 1%未満に減らすことに成功しました。 

partialWake.png

この変更により、作業が完了せずにタイムアウトするインスタンスが減少し、平均実行時間が短縮されました。

バックグラウンド作業の効率を改善したいと考えている他のデベロッパーに対する WHOOP チームのアドバイスは次のとおりです。

sarthak.png

使ってみる

アプリの過度な部分的な wake lock を減らしたり、ワーカーの効率を改善したりすることに関心がある場合は、Android Vitals でアプリの過度な部分的な wake lock の指標を確認し、wake lock のドキュメントでベスト プラクティスとデバッグ戦略の詳細を確認してください。

作成者:

続きを読む