アプリは多くの場合、一度に複数の処理を行う必要があります。Android API には、これを行うためのさまざまな方法が用意されています。適切なオプションを選択することは非常に重要です。あるオプションが、ある状況では適切なものでも、別の状況では非常に不適切なものになる場合もあります。間違った API を選択すると、アプリのパフォーマンスやリソースの効率が悪くなり、バッテリーが消耗するだけでなく、ユーザー デバイス全体のパフォーマンスが低下する可能性があります。間違った方法を選択すると、アプリが Google Play ストアに掲載されなくなることがあります。
このドキュメントでは、利用可能なさまざまなオプションについて説明し、状況に適したオプションを選択する方法について説明します。
用語
バックグラウンド処理に関連する重要な用語の中には、矛盾した複数の方法で使用されることがあります。そのため、用語を定義することが重要です。
アプリがバックグラウンドで実行されている場合、システムによってさまざまな制限が課されます。(たとえば、ほとんどの場合、バックグラウンドのアプリはフォアグラウンド サービスを起動できません)。
このドキュメントでは、「タスク」という用語を、アプリがメイン ワークフローの外部で実行するオペレーションを指します。理解を一致させるために、タスクは主に非同期処理、バックグラウンド処理、フォアグラウンド サービスという 3 つのカテゴリに分類しています。
適切なオプションを選択する
ほとんどのシナリオでは、タスクのカテゴリ(非同期処理、バックグラウンド処理、またはフォアグラウンド サービス)を判断することで、タスクに適した API を判断できます。
判断に迷う場合は、提供されるフローチャートを使用すると、判断をより詳細に行うことができます。これらの各オプションについては、このドキュメントの後半で詳しく説明します。
バックグラウンド処理では、主に次の 2 つのシナリオを考慮する必要があります。
この 2 つのシナリオには独自のディシジョン ツリーがあります。
非同期処理
多くの場合、アプリはフォアグラウンドで実行されている間に同時実行オペレーションを行うだけで済みます。たとえば、アプリで時間のかかる計算が必要になることがあります。UI スレッドで計算が行われた場合、計算が終了するまでユーザーはアプリを操作できず、ANR エラーが発生する可能性があります。このような場合、アプリは非同期処理オプションを使用する必要があります。
一般的な非同期処理のオプションには、Kotlin コルーチンと Java スレッドがあります。詳細については、非同期処理のドキュメントをご覧ください。バックグラウンド処理とは異なり、アプリが有効なライフサイクル ステージで停止した場合(たとえば、アプリがフォアグラウンドから離れた場合)は、非同期処理が完了するとは限りません。
バックグラウンド処理
ユーザーがアプリを離れた場合でも継続する必要がある処理が必要な場合は、バックグラウンド処理のほうが柔軟性の高いオプションとなります。ほとんどの場合、バックグラウンド処理に最適なのは 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 を使用して簡単にジョブを処理できます。たとえば、ユーザーが特定の場所に到達したときにアプリでアクションを実行する必要がある場合は、フォアグラウンド サービスでユーザーの位置情報をトラッキングする代わりに、geofence API を使用することをおすすめします。
イベントに応じたタスク
アプリは、トリガーに応じて次のようなバックグラウンド処理が必要になることがあります。
これは、外部トリガー(FCM メッセージなど)の場合もあれば、アプリ自体によって設定されたアラームに応じて行われる場合もあります。たとえば、ゲームが一部のアセットを更新するように指示する FCM メッセージを受信することがあります。
タスクが数秒で完了することがわかっている場合は、非同期処理を使用してタスクを実行します。アプリがバックグラウンドにあっても、数秒間のタスクが自動で実行されます。
タスクに数秒かかる場合は、フォアグラウンド サービスを起動してタスクを処理することをおすすめします。実際、アプリが現在バックグラウンドにある場合でも、タスクがユーザーによってトリガーされ、承認されているバックグラウンド起動の制限の例外のいずれかに該当する場合は、フォアグラウンド サービスの開始が許可される可能性があります。たとえば、アプリが優先度の高い FCM メッセージを受信した場合、そのアプリは、バックグラウンドにあってもフォアグラウンド サービスを開始できます。
タスクに数秒かかる場合は、バックグラウンド処理を使用します。