プロダクト ニュース

Android Vitals の wake lock 指標を使用してアプリのバッテリーを最適化する

所要時間: 7 分
Alice Yuan
デベロッパー リレーション エンジニア

バッテリー駆動時間はユーザー エクスペリエンスの重要な側面であり、wake lock は重要な役割を果たします。過度に使用していませんか?このブログ投稿では、wake lock とは何か、wake lock を使用する際のベスト プラクティス、Google Play Console の指標を使用してアプリの動作をより深く理解する方法について説明します。

Android Vitals での過度の部分的な wake lock の使用

Google Play Console では、過度の部分的な wake lock の使用を主要な重要業績評価指標として、バッテリーの消耗をモニタリングできるようになりました。

この機能により、既存のコア指標の安定性インジケーター(ユーザーが認識する過剰なクラッシュと ANR)とともに、バッテリー効率の重要性が高まります。過度の wake lock の不正な動作のしきい値を定義しました。2026 年 3 月 1 日以降、タイトルがこの品質基準を満たしていない場合、おすすめなどの目立つ検索面にタイトルが表示されなくなる可能性があります。場合によっては、アプリが過剰なバッテリーの消耗を引き起こす可能性があることをユーザーに知らせる警告がストアの掲載情報に表示されることがあります。

warning.png

Android Vitals の概要の過度の wake lock の警告。

モバイル デバイスの場合、Android Vitals 指標は、画面がオフでアプリがバックグラウンドで実行されているかフォアグラウンド サービスを実行している間に取得された、除外されていない wake lock に適用されます。Android Vitals は、次の場合に部分的な wake lock の使用量が過度であると判断します。

  • ウェイクロックは 24 時間の間に少なくとも 2 時間保持されます。
  • 28 日間の平均で、アプリのセッションの 5% 以上に影響している。

音声位置情報JobScheduler ユーザー開始 API によって作成された wake lock は、wake lock の計算から除外されます。

wake lock について

ウェイクロックは、ユーザーがデバイスを操作していない場合でも、アプリがデバイスの CPU を動作させ続けることができるメカニズムです。

部分的な wake lock では、画面がオフでも CPU が動作し続けるため、CPU が低電力の「一時停止」状態になるのを防ぐことができます。完全な wake lock では、画面と CPU の両方が動作し続けます。

部分ウェイクロックを取得する方法は 2 つあります。

  • アプリが特定のユースケースで PowerManager API を使用してウェイクロックを手動で取得および解放している場合。多くの場合、これは フォアグラウンド サービス(ユーザーが認識できるオペレーションを目的としたプラットフォーム ライフサイクル API)と組み合わせて取得されます。
  • また、別の API によってウェイクロックが取得され、その API の使用によりアプリに割り当てられることもあります。詳しくは、ベスト プラクティスのセクションをご覧ください。

ウェイクロックは、ユーザーが開始した大きなファイルのダウンロードを完了するなどのタスクに必要ですが、過度または不適切な使用はバッテリーの著しい消耗につながる可能性があります。アプリがウェイクロックを数時間保持したり、適切に解放しなかったりするケースが確認されています。これにより、ユーザーがアプリを操作していない場合でも、バッテリーの消耗が著しいという苦情が寄せられています。

ウェイクロックの使用に関するベスト プラクティス

ウェイクロックの過剰な使用をデバッグする方法を説明する前に、ウェイクロックのベスト プラクティスに沿って対応していることを確認してください。

次の 4 つの重要な質問について検討してください。


1. 代替のウェイクロック オプションを検討しましたか?

手動部分 wake lock の取得を検討する前に、次の意思決定フローチャートに従ってください。

wakelock.png

wake lock を手動で取得するタイミングを判断するためのフローチャート

  1. 画面をオンのままにする必要がありますか?
  2. アプリケーションがフォアグラウンド サービスを実行しているか?
    • いいえ: ウェイクロックを手動で取得する必要はありません。
  3. デバイスが一時停止すると、ユーザー エクスペリエンスに悪影響を及ぼしますか?
    • 不要: たとえば、デバイスが起動した後に通知を更新する場合、ウェイクロックは必要ありません。
    • はい: 外部デバイスとの通信が継続しているなど、デバイスが一時停止しないようにすることが重要な場合は、続行します。
  4. デバイスを代わりに起動状態に保つ API がすでに存在するかどうか。
  5. これらの質問にすべて回答し、代替手段がないと判断した場合は、手動でウェイクロックを取得する手順に進みます。

2. ウェイクロックに正しい名前を付けていますか?

ウェイクロックを手動で取得する場合は、デバッグのために適切な名前を付けることが重要です。

  • 名前にメールアドレスなどの個人を特定できる情報(PII)を含めないようにします。PII が検出されると、ウェイクロックが _UNKNOWN として記録され、デバッグが妨げられます。
  • クラス名やメソッド名を使用してウェイクロックをプログラムで命名しないでください。Proguard などのツールで難読化される可能性があるためです。代わりに、ハードコードされた文字列を使用します。
  • wake lock タグにカウンタまたは一意の識別子を追加しないでください。ウェイクロックが実行されるたびに同じタグを使用することで、システムが名前別に使用状況を集計できるようになり、異常な動作を検出しやすくなります。

3. 取得したウェイクロックは常に解放されますか?

wake lock を手動で取得する場合は、wake lock の解放が常に実行されるようにしてください。wake lock を解放しないと、バッテリーの消耗が著しくなる可能性があります。

たとえば、processingWork() の実行中にキャッチされない例外がスローされると、release() 呼び出しは発生しない可能性があります。代わりに、try-finally ブロックを使用して、例外が発生した場合でも wake lock が確実に解放されるようにすることができます。

また、wake lock にタイムアウトを追加して、一定期間後に解放されるようにし、無期限に保持されないようにすることもできます。

fun processingWork() {
    wakeLock.apply {
        try {
            acquire(60 * 10 * 1000) // timeout after 10 minutes
            doTheWork()
        } finally {
            release()
        }
    }
}

4. 起動頻度を減らすことはできますか?

定期的なデータ リクエストの場合、バッテリーの最適化には、アプリがデバイスを起動する頻度を減らすことが重要です。起動頻度を減らす例としては、次のようなものがあります。

  • WorkManager: PeriodicWorkRequest の定期的な間隔を増やします。
  • SensorManager: リスナーを登録する際に maxReportLatencyMs を指定してバッチ処理を活用します。
  • Fused Location Provider:
    • 最新のキャッシュ保存された位置情報に getLastLocation を使用して、位置情報の取得頻度を減らします。
    • バッテリー消費の少ない更新方法には、setPriority(PRIORITY_PASSIVE) を使用します。
    • また、setMinUpdateIntervalMillis で最小更新間隔を設定することで、位置情報のバッチ処理メカニズムを活用できます。

詳しくは、wake lock のベスト プラクティスのドキュメントをご覧ください。

過度の wake lock 使用をデバッグする

最善の意図があっても、wake lock の使用量が過剰になることがあります。Google Play Console でアプリにフラグが付けられた場合は、次の手順でデバッグします。

Google Play Console での初回確認

Android Vitals の過剰な部分的な wake lock のダッシュボードには、アプリに関連付けられている除外されていない wake lock 名の内訳が表示され、影響を受けたセッションと期間を確認できます。ドキュメントを使用して、ウェイクロック名がアプリによって保持されているか、別の API によって保持されているかを確認するよう促すリマインダー。

breakdowns2.png

Android Vitals の過度の部分的な wake lock のダッシュボードをスクロールして、内訳セクションで過度の wake lock タグを表示した状態。

ワーカー/ジョブによって保持されている過剰なウェイクロックのデバッグ

ワーカーが保持するウェイクロックは、次のウェイクロック名で識別できます。

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

Worker が保持する wake lock 名のバリエーションの完全なリストは、ドキュメントで確認できます。これらのウェイクロックをデバッグするには、Background Task Inspector を使用してローカルでデバッグするか、getStopReason を利用してフィールドで問題をデバッグします。

Android Studio の Background Task Inspector

taskinspector.png


Background Task Inspector のスクリーン キャプチャ。頻繁に再試行して失敗したワーカー「WeatherSyncWorker」を特定できています。

WorkManager の問題をローカルでデバッグするには、エミュレータまたは接続済みのデバイス(API レベル 26 以上)でこのツールを使用します。ワーカーとそのステータス(完了、実行中、キューに登録済み)のリストが表示され、詳細を検査してワーカー チェーンを把握できます。

たとえば、システム制限に達したためにワーカーが頻繁に失敗したり再試行したりしているかどうかを確認できます。

詳しくは、Background Task Inspector のドキュメントをご覧ください。

WorkManager getStopReason

過剰なウェイクロックを使用するワーカーのフィールド内デバッグには、WorkManager 2.9.0 以降では WorkInfo.getStopReason() を、JobScheduler では SDK 31 以降で利用可能な JobParameters.getStopReason() を使用します。

この API は、ワーカーが停止した理由(STOP_REASON_TIMEOUTSTOP_REASON_QUOTA など)をログに記録し、ランタイム期間の超過による頻繁なタイムアウトなどの問題を特定するのに役立ちます。

backgroundScope.launch {
    WorkManager.getInstance(context)
        .getWorkInfoByIdFlow(workRequest.id)
        .collect { workInfo ->
            logStopReason(workRequest.id, workInfo?.stopReason)
        }
}

詳しくは、タスク スケジューリング API のバッテリー使用量を最適化するをご覧ください。

その他の種類の過剰な wake lock のデバッグ

手動で保持されたウェイクロックやウェイクロックを保持する API を含むより複雑なシナリオでは、システム トレース収集を使用してデバッグすることをおすすめします。

システム トレースの収集

システム トレース は、一定期間のシステム アクティビティの詳細な記録をキャプチャする強力なデバッグツールです。CPU の状態、スレッド アクティビティ、ネットワーク アクティビティ、ジョブの継続時間やウェイクロックの使用量などのバッテリー関連の指標に関する分析情報を提供します。

システム トレースは、次の複数の方法でキャプチャできます。

powermgmt.png

Perfetto UI の [Android apps & svcs] タブで「power:PowerManagement」Atrace カテゴリを有効にします。 

選択した方法に関係なく、デバイスの状態トラックを表示できるようにするには、「power:PowerManagement」Atrace カテゴリを収集していることを確認することが重要です。

Perfetto UI の検査と SQL 分析

システム トレースは Perfetto UI で開いて検査できます。トレースを開くと、タイムライン上にさまざまなプロセスの可視化が表示されます。このガイドで取り上げるトラックは、[デバイスの状態] にあるものです。

perfetto.png


[デバイスの状態] の [最上位アプリ]、[画面の状態]、[長時間実行中の wake lock]、[ジョブ] などのトラックを固定して、長時間実行中の wake lock スライスを視覚的に特定します。

各ブロックには、イベントの名前、イベントの開始日時、終了日時が一覧表示されます。Perfetto では、これはスライスと呼ばれます。

複数のトレースをスケーラブルに分析するには、Perfetto の SQL 分析を使用します。SQL クエリを使用すると、持続時間で並べ替えられたすべてのウェイクロックを検索できます。これにより、過剰な使用の主な原因を特定できます。

システム トレースで発生したすべての wake lock タグを合計し、合計時間で並べ替えるクエリの例を次に示します。

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 の過度の部分的な wake lock の指標は、バッテリーの消耗の削減とアプリの品質向上をサポートする Google の継続的な取り組みのほんの一部にすぎません。

wake lock を理解して適切に実装することで、アプリのバッテリー パフォーマンスを大幅に最適化できます。代替 API の活用、wake lock のベスト プラクティスの遵守、Background Task Inspector、システム トレース、ProfilingManager などの強力なデバッグツールの使用は、Google Play でアプリを成功させるための鍵となります。

作成者:

続きを読む