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