https://developer.android.com/about/versions/oreo/background?hl=ja
[写経]:自分用
バックグラウンド制限
システム負荷などで、アプリの予期せぬシャットダウンを回避するため、アプリを直接操作してない時のアプリの実行動作を制限します。制限する方法は次の2つです。
バックグラウンドサービス制限
- アプリがアイドル状態となると、バックグラウンドサービスを制限
- フォアグラウンドサービスには制限は適用しない
ブロードキャスト制限
Android7.0(API24)以降で制限を課し、Android8.0(API26)で制限を強化している
限定的な例外を除き
- アプリはマニフェストを使用して、暗黙的なブロードキャストを登録できない。
- ただしアプリ実行時であれば暗黙的なブロードキャストを登録できる。
- アプリはマニフェストを使用して、明示的なブロードキャストを登録できる。
制限とAPIレベル
Note: デフォルトでは、これらの制限はAndroid8.0(API26)以降を対象とするアプリにのみ適用。 ただしアプリがAPI26未満を対象としている場合でも、ユーザーは[Settings]画面でアプリに対してこれらの制限の大半を有効にできます。(制約を設けたほうがユーザーエクスペリエンスの質を担保するでしょう) |
多くの場合、アプリはJobSchedulerで処理することで制限を回避できます。
JobSchedulerは、アプリがアクティブでない時に、処理を実行するように調整させますが、ユーザーエクスペリエンスに影響しないように処理をスケジュールすることもできます。
Android 8.0 では、JobSchedulerにいくつかの改善が追加されており、サービスとブロードキャスト レシーバーをスケジュールされたジョブに簡単に置き替えることができます。詳細については、JobScheduler の改善をご覧ください。
JobScheduler:
いろんな処理を、効率よく実行するように、タスク管理するスケジュールサービス。
バックグラウンドサービスの制限
フォアグランドとみなされる場合
- 可視アクティビティがある(一時停止されていたも可)
- フォアグラウンドサービスを利用
- アプリが他のフォアグランドアプリと接続されており、フォアグランドアプリのサービスのどれか一つにバインドしている
- アプリが他のフォアグランドアプリと接続されており、フォアグランドアプリのコンテントプロバイダを使っている
= 他のフォアグランドアプリのバインド例 = - IME
- Wallpaper service
- Notification listener
- Voice or text service
これら以外の状態なら、アプリはバックグラウンド処理とみなされます。
Note: 上記のルールはバインドされたサービスには適用しません。アプリでバインドされたサービスを定義してる場合、アプリがフォアグランドにあろうとなかろうと、別のコンポーネントをそのサービスにバインドできます。 |
システムによるバックグラウンドアプリの終了
アプリがフォアグランドで実行されている間は、自由にフォアグランドやバックグラウンドサービスを生成したり実行できます。アプリがバックグラウンドに移ると、数分間だけサービスを生成したり実行する余裕が生まれますが、それが過ぎるとシステムはアプリをアイドル状態と判定し、Service.stopSelf()メソッドを使った時のように、アプリのバックグラウンドサービスを停止します。
アプリのホワイトリストへの追加
アプリがホワイトリストに入る条件は、以下のようにユーザーが視認できる処理をしてる時です。
特定の条件のもと、バックグラウンドアプリはテンポラリーなホワイトリストに入り、数分間は自由にサービスを起動できて、実行も許可されます。
- 高い優先度のFirebase Cloud Messageing (FCM)メッセージの処理
- ブロードキャストの受信(SMS/MMSメッセージなど)
- 通知からのPendingIntentの実行
- VPNアプリが、自信をフォアグラウンドにプロモートする前の、VpnServiceの開始
IntentService/JobIntentServiceとAndroid8.0以降
IntentServiceでバックグラウンドサービスを扱っている場合
Note: IntentServiceはサービスなので、バックグラウンドサービスに対する新しい制限事項の対象になります。ですので、IntentServiceに依存するアプリは、Android8.0以降では正常に動作しません。 こうした理由からAndroid Support Library 26.0.0では、新しくJobIntentServiceクラスを導入しました。このクラスはIntentServiceと同じ機能を提供しますが、Android8.0以降で実行されるとき、サービスの代わりにジョブを使用します。 |
JobScheduler
多くの場合、アプリはバックグラウンドサービスをJobSchedulerのジョブに置き換えられます(Android8.0:API26以降に移行する場合など)。スケジュールされたジョブは、定期的に起動され、サーバーに対してクエリを実行して終了します。
Android8.0前後でのバックグラウンドサービス生成
Android8.0以前では、バックグラウンドサービスを作成する方法として、バックグラウンドサービスを作成してから、そのサービスをフォアグラウンドにプロモートしてます。
Android8.0以降では、システムはバックグラウンドアプリによるバックグランドサービスの作成を許可しなくなってます。その代わりに、startForegroundService()メソッドが導入されており、このメソッドを使って、フォアグラウンドで新しいサービスを開始います。
startForegroundService()を実行したら、5秒以内にstartForeground()を呼びだし、新しいサービスの通知(notification)をユーザーに表示します。アプリが制限時間内にstartForeground()を呼ばないと、システムによってサービスは停止され、アプリがANR(application not respondeing)となります。
ブロードキャストの制限 省略
移行
API26未満を対象にバックグラウンド制限を適用する方法を紹介します。バックグラウンド制限を設けることは、ユーザーエクスペリエンスの質を保つことに繋がります。
API26未満でも**[settings]**画面でアプリに対して制限を有効にできます。新しい
制限に準拠するため、アプリをアップデートする必要があるケースがあります。
置き換える必要がある場合
- アプリがアイドル状態のときに、バックグランドサービスの処理に依存してる
- マニフェストで暗黙的ブロードキャストに対してレシーバを宣言してる
アプリがアイドル状態のときに、そのアプリがバックグラウンドサービスの処理に依存してる場合、そのアプリは、これらのサービスを置き換える必要があります。
<置き換える方法>
-
アプリがバックグラウンドにあり、フォアグラウンドサービスを作成する場合
startForegroundServiceメソッドを、startService()の代わりに使用して、フォアグランドサービスを生成 -
ユーザーに表示するサービスはフォアグラウンドサービスにする
startForegroundServiceメソッドを、startService()の代わりに使用して、フォアグランドサービスを生成 -
スケジュールされたジョブを使ってサービス機能を複製
一般的に、ユーザーが認識できる状況で稼働してないサービスの代わりとして、スケジュールされたジョブを使う -
バックグラウンドでポーリングせず、FCMを使ってネットワークイベントが発生したときにアプリを選択的に起動する
ポーリング:一定間隔で他のシステムに問い合わせする -
アプリが自然にフォアグランドになるまでバックグランド動作を保留
アプリのマニフェストで定義されているブロードキャストレシーバーを確認。マニフェストで暗黙的なブロードキャストに対してレシーバーを宣言してる場合、それを置き換える必要があります。考えられる解決策は以下です。
<置き換える方法>
-
マニフェストでレシーバーを宣言するのではなく、Context.registerReceiver()を呼び出し、実行時にレシーバーを作成する
-
スケジュールされたジョブを使って、暗黙的なブロードキャストのきっかけ条件を確認します