Task Scheduling API のバッテリー使用量を最適化する

このページでは、適切に動作するバックグラウンド タスクをセットアップするためのベスト プラクティスをいくつか紹介します。これらのベスト プラクティスは特にバッテリー消費量の削減を目的としていますが、ネットワーク使用量の削減など、他の方法でデバイスのパフォーマンスを向上させることもできます。

最適な制約を選択してタスクを組み合わせる

タスクがデバイスにかかる負荷を最小限に抑えるには、最適な制約を指定することが重要です。(JobScheduler ジョブの制約のリストについては、JobInfo.Builder をご覧ください)。たとえば、アプリがバッテリーを消耗しないようにするには、RequiresCharging 制約を指定することをおすすめします。この制約は、電池残量が実際に増加していない限りジョブを実行しないようにシステムに指示します。同様に、Wi-Fi を使用する場合、一般的にモバイルデータよりも消費電力が小さいため、ネットワーク接続が必要なタスクでは、定額制ネットワークが利用可能になるまで待機できる場合は、NetworkType.UNMETERED 制約を設定することをおすすめします。

また、同じ制約が適用される類似したタスクが複数ある場合は、通常、それらを 1 つのタスクに統合して、デバイスが 1 回だけ起動されるようにすることをおすすめします。たとえば、アプリに 3 つの異なるデータセットがあり、クラウド ストレージと同期する必要があるとします。3 つの異なるタスク(データセットごとに 1 つ)をスケジュールするのではなく、1 つの「データの同期」タスクをスケジュールし、適切な制約を定義して、そのタスクの実行時に保留中のデータ同期をすべて実行させることをおすすめします。

とは言え、無関係なタスクを 1 つのタスクに結合しようとしないでください。各タスクに適切な制約を設定するようにしてください。たとえば、タスクの優先度が低い場合は、デバイスがアイドル状態で充電中のときに実行するように指定します。こうすることで、デバイスが数回復帰しても、ユーザー エクスペリエンスが損なわれたり、バッテリー駆動時間が短くなったりすることはありません。

時間的制約があるタスクのみ優先としてマークする

タスクが特に緊急の場合は、優先マークを付けることができます。(JobScheduler ジョブの場合は、JobInfo.Builder.setExpedited(true) を呼び出します)。これにより、さまざまな方法でタスクの優先順位付けが行われます。たとえば、システムは可能なときにすぐにこれらのタスクを実行しますが、電源管理の制限が優先タスクに影響する可能性は低くなります。

このような理由から、必要なときにのみタスクに「優先」のマークを付けるよう注意する必要があります。優先タスクはシステム効率の一部をオーバーライドできるため、優先タスクは、そのようにマークされていない場合よりも多くの電力を消費する可能性があります。

優先するタスクは時間的制約があり、タスクの実行に時間がかかるとユーザー エクスペリエンスが損なわれる場合にのみ使用してください。たとえば、アプリが優先度の高い FCM メッセージを処理するタスクを実行している場合は、そのタスクに優先としてマークするのが適切です。ただし、システムの最適化をオーバーライドするためだけに、タスクを「優先」としてマークしないでください。

タスクが停止された理由を確認する

タスクが完了前に停止した場合は、WorkInfo.getStopReason() を呼び出すことで、停止した理由を確認できます。(JobScheduler ジョブの場合は、JobParameters.getStopReason() を呼び出します。これはいくつかの理由から重要です。当然ながら、まずはタスクを完了する必要があります。タスクが停止した理由を調べると、同様の状況を回避できます。ただし、システム リソースを過剰に消費する動作が原因で、システムがタスクを停止する可能性もあります。バッテリーやネットワークを不必要に使用することで、アプリが悪質なユーザーにならないようにします。

たとえば、STOP_REASON_TIMEOUT を理由にタスクが頻繁に停止する場合は、タスクに予想よりもはるかに長い時間がかかるエッジケースがある可能性があります。

分析エンジンを使用して、アプリのタスクが停止しているかどうか、停止した理由を確認することをおすすめします。