アプリは多くの場合、一度に複数の処理を行う必要があります。Android API には、これを行うためのさまざまな方法が用意されています。適切なオプションを選択することは非常に重要です。あるオプションが、ある状況では適切でも、別の状況では非常に間違っている場合もあります。間違った API を選択すると、アプリのパフォーマンスやリソースの効率が損なわれ、バッテリーの消耗や、ユーザーのデバイス全体のパフォーマンスの低下を招く可能性があります。間違った方法を選択すると、アプリが Google Play ストアに掲載されないことがあります。
このドキュメントでは、利用可能なさまざまなオプションについて説明し、状況に適したオプションを選択できるようにします。
用語
バックグラウンド タスクに関連する重要な用語の中には、矛盾する複数の方法で使用されることがあります。そのため、利用規約を定義することが重要です。
アプリがバックグラウンドで実行されている場合、システムはアプリにいくつかの制限を加えます。(たとえば、ほとんどの場合、バックグラウンドのアプリはフォアグラウンド サービスを起動できません)。
このドキュメントでは、「タスク」という用語は、アプリがメイン ワークフローの外部で実行しているオペレーションを意味します。理解を整合させるために、このタスクは、非同期処理、タスク スケジューリング API、フォアグラウンド サービスという 3 つの主要なタスクカテゴリに分類しています。
適切なオプションを選択する
ほとんどのシナリオでは、タスクのカテゴリ(非同期処理、タスク スケジューリング API、またはフォアグラウンド サービス)を把握することで、タスクに適した API を判断できます。
判断に迷う場合は、提供されるフローチャートを使用して、判断にさらにニュアンスを追加できます。これらの各オプションについては、このドキュメントの後半で詳しく説明します。
バックグラウンド タスクについて考慮すべき主なシナリオは 2 つあります。
この 2 つのシナリオには独自のディシジョン ツリーがあります。
非同期処理
多くの場合、アプリはフォアグラウンドで実行されている間に同時実行オペレーションを行うだけで済みます。たとえば、アプリで計算に時間がかかる場合です。UI スレッドで計算を行った場合、計算が完了するまでユーザーはアプリを操作できず、ANR エラーが発生する可能性があります。このような場合、アプリは非同期処理オプションを使用する必要があります。
一般的な非同期処理のオプションには、Kotlin コルーチンや Java スレッドがあります。詳細については、非同期処理のドキュメントをご覧ください。バックグラウンド タスク API とは異なり、アプリが有効なライフサイクル ステージでなくなった場合(たとえば、アプリがフォアグラウンドから離れた場合)は、非同期処理が完了する保証はありません。
タスク スケジューリング API
ユーザーがアプリを離れても続行する必要があるタスクを実行する必要がある場合は、タスク スケジューリング API の方が柔軟性の高いオプションです。ほとんどの場合、バックグラウンド タスクの実行には WorkManager を使用することをおすすめしますが、プラットフォームの JobScheduler
API の使用が適切な場合もあります。
WorkManager は、シンプルなジョブから複雑なジョブを必要に応じて設定できる強力なライブラリです。WorkManager を使用すると、特定の時刻に実行されるようタスクのスケジュールを設定したり、タスクを実行する条件を指定したりできます。タスクのチェーンを設定して、各タスクを順番に実行し、その結果を次のタスクに渡すようにすることもできます。使用可能なすべてのオプションについては、WorkManager 機能リストをご覧ください。
バックグラウンド タスクの一般的なシナリオは次のとおりです。
- サーバーから定期的にデータを取得しています
- センサーデータ(歩数計データなど)の取得
- 定期的に位置情報を取得する(Android 10 以降では
ACCESS_BACKGROUND_LOCATION
権限が付与されている必要があります) - カメラによって作成された写真など、コンテンツ トリガーに基づいてコンテンツをアップロードする
フォアグラウンド サービス
フォアグラウンド サービスは、中断すべきでないタスクをすぐに実行する優れた方法を提供します。ただし、フォアグラウンド サービスはデバイスに高い負荷がかかる可能性があり、プライバシーとセキュリティに影響することもあります。このような理由から、システムは、アプリがフォアグラウンド サービスを使用する方法とタイミングについて多くの制限を課しています。たとえば、フォアグラウンド サービスはユーザーが認識できる必要があります。ほとんどの場合、アプリがバックグラウンドで動作しているときは、フォアグラウンド サービスを起動できません。詳細については、フォアグラウンド サービスのドキュメントをご覧ください。
フォアグラウンド サービスを作成する方法は 2 つあります。Service.startForeground()
を呼び出すことで、独自の Service
を宣言し、サービスがフォアグラウンド サービスであることを指定できます。また、長時間実行ワーカーのサポートで説明されているように、WorkManager を使用してフォアグラウンド サービスを作成することもできます。ただし、WorkManager によって作成されたフォアグラウンド サービスは、他のフォアグラウンド サービスと同じ制限をすべて遵守する必要がある点に注意してください。WorkManager は、フォアグラウンド サービスの作成を簡素化するための便利な API を提供するだけです。
代替 API
より具体的なユースケースでパフォーマンスが向上するように設計された代替 API がシステムによって提供される。ユースケースに代替 API が存在する場合は、フォアグラウンド サービスの代わりにその API を使用することをおすすめします。これにより、アプリのパフォーマンスが向上します。フォアグラウンド サービス タイプのドキュメントでは、特定のフォアグラウンド サービス タイプの代わりに使用できる適切な API がある場合に説明しています。
代替 API を使用する最も一般的なシナリオは次のとおりです。
- データ同期フォアグラウンド サービスを作成する代わりに、ユーザーが開始するデータ転送を使用して大規模なダウンロードまたはアップロードを行う
- Bluetooth ペア設定とデータ転送に、接続されたデバイスのフォアグラウンド サービスを使用する代わりに、コンパニオン デバイス マネージャーを使用する
- メディア再生フォアグラウンド サービスを作成する代わりに、ピクチャー イン ピクチャー モードを使用して動画を再生する
ユーザーが開始したタスク
アプリでバックグラウンド タスクを実行する必要があり、アプリが表示されている間にユーザーが処理を開始する場合は、以下の質問に答えて適切なアプローチを見つけてください。
アプリがバックグラウンドで実行されている間もタスクの実行を継続する必要がありますか?
アプリがバックグラウンドで実行されている間にタスクの実行を継続する必要がない場合は、非同期処理を使用してください。非同期処理にはさまざまな方法があります。重要なのは、アプリがバックグラウンドに移行すると、これらのオプションはすべて動作を停止する点です。(アプリをシャットダウンすると、アプリも停止します)。たとえば、ソーシャル メディア アプリでコンテンツ フィードを更新する場合、ユーザーが画面を離れた場合は操作を完了する必要はありません。
タスクが延期または中断された場合、ユーザー エクスペリエンスが低下することはありませんか?
タスクが延期またはキャンセルされた場合にユーザー エクスペリエンスが損なわれるかどうかを検討することが重要です。たとえば、アプリでアセットを更新する必要がある場合、ユーザーはオペレーションがすぐに発生するのか、デバイスの充電中の真夜中に発生するのかに気づかない可能性があります。このような場合は、バックグラウンド処理オプションを使用してください。
短期的で重要なタスクか?
タスクが遅延できず、迅速に完了する場合は、shortService
タイプのフォアグラウンド サービスを使用できます。これらのサービスは他のフォアグラウンド サービスよりも簡単に作成でき、それほど多くの権限は必要ありません。ただし、短時間のサービスは 3 分以内に完了する必要があります。
この目的のためだけの代替 API はありますか?
タスクがユーザーに表示されない場合、適切な解決策はフォアグラウンド サービスを使用することです。これらのサービスは、起動すると継続的に実行されるため、タスクを中断した場合にユーザー エクスペリエンスが低下する場合に適しています。たとえば、ワークアウト記録アプリでは、位置センサーを使用して、ユーザーがジョギング ルートを地図上に記録できます。タスクが一時停止されるとトラッキングが直ちに停止するため、バックグラウンド処理オプションではこの処理はおすすめしません。このような状況では、フォアグラウンド サービスが最も理にかなっています。
ただし、フォアグラウンド サービスは多くのデバイス リソースを使用する可能性があるため、いつどのように使用できるかについては多くの制限が課されます。多くの場合、フォアグラウンド サービスを使用する代わりに、手間をかけずにジョブを処理する代替 API を使用できます。たとえば、ユーザーが特定の場所に到達したときにアプリでアクションを実行する必要がある場合は、フォアグラウンド サービスでユーザーの位置情報を追跡するのではなく、Geoofence API を使用することをおすすめします。
イベントに応じたタスク
アプリは、トリガーに応じて次のようなバックグラウンド処理を行う必要があります。
これは、外部トリガー(FCM メッセージなど)の場合もあれば、アプリ自体によって設定されたアラームに応答する場合もあります。たとえば、ゲームが一部のアセットを更新するように指示する FCM メッセージを受信する場合があります。
タスクが数秒で完了することが確実である場合は、非同期処理を使用してタスクを実行します。アプリがバックグラウンドにあっても、数秒間はこのようなタスクを実行できます。
タスクに数秒以上かかる場合は、フォアグラウンド サービスを開始してタスクを処理することをおすすめします。実際、アプリが現在バックグラウンドにある場合でも、タスクがユーザーによってトリガーされ、承認されたバックグラウンド開始制限の除外のいずれかに該当する場合、フォアグラウンド サービスの開始が許可されている可能性があります。たとえば、優先度の高い FCM メッセージを受信したアプリは、バックグラウンドにあってもフォアグラウンド サービスを開始できます。
タスクに数秒以上かかる場合は、タスク スケジューリング API を使用します。