page.title=バックグラウンド処理の最適化 page.metaDescription=暗黙的なブロードキャストに対する新しい制限。 page.keywords="android N", "implicit broadcasts", "job scheduler" page.image=images/cards/card-nyc_2x.jpg @jd:body
バックグラウンド処理が多くのメモリと電池を消費する場合があります。たとえば、多くのバックグラウンド処理が暗黙的なブロードキャストをリッスンするように登録されていますが、バックグラウンド処理が有用でない場合でも、暗黙的なブロードキャストによりこれらの処理が開始されることがあります。 バックグラウンド処理が端末のパフォーマンスとユーザー エクスペリエンスの両方に多大な影響を及ぼす可能性があります。
Android N では、こういった問題を緩和するために、以下の制限が適用されます。
アプリでこれらのインテントのいずれかを使用する場合は、Android N 端末を適切にターゲットにできるように、可能な限りインテントとの依存性を削除する必要があります。 Android フレームワークは、これらの暗黙的なブロードキャストの必要性を軽減するいくつかのソリューションを提供します。 たとえば、{@link android.app.job.JobScheduler} と {@code GcmNetworkManager} は、従量制ではないネットワークへの接続など、指定条件が満たされたときに、ネットワーク操作をスケジュールするための堅牢なメカニズムを提供します。 また、コンテンツ プロバイダの変更に対応するために、{@link android.app.job.JobScheduler} を使用することもできます。{@link android.app.job.JobInfo} オブジェクトは、{@link android.app.job.JobScheduler} がジョブをスケジュールするために使用するパラメータをカプセル化します。 ジョブの条件が満たされると、システムはこのジョブをアプリの {@link android.app.job.JobService} で実行します。
このドキュメントでは、アプリをこれらの新しい制限に対応させるために、 {@link android.app.job.JobScheduler} などの代替メソッドの使用法について説明します。
Android N 向けのアプリは、マニフェストで {@link android.net.ConnectivityManager#CONNECTIVITY_ACTION} ブロードキャストの受信登録をしていても、このブロードキャストを受信しません。また、このブロードキャストに依存している処理は開始されません。 これにより、ネットワークの変更をリッスンするアプリ、または端末が従量制ではないネットワークに接続したときにネットワーク アクティビティをまとめて実行するアプリに問題が発生する可能性があります。 Android フレームワークは、この制限を回避するためのいくつかのソリューションを備えていますが、アプリで実行するタスクに応じて、適切なソリューションを選択してください。
注: {@link android.content.Context#registerReceiver Context.registerReceiver()} で登録された {@link android.content.BroadcastReceiver} は、アプリが実行中のときにこれらのブロードキャストを継続して受信します。
{@link android.app.job.JobInfo} オブジェクトをビルドするために {@link android.app.job.JobInfo.Builder JobInfo.Builder} を使用するときは、{@link android.app.job.JobInfo.Builder#setRequiredNetworkType setRequiredNetworkType()} メソッドを適用し、{@link android.app.job.JobInfo JobInfo.NETWORK_TYPE_UNMETERED} をジョブ パラメータとして渡します。 次のコードサンプルは、端末が従量制ではないネットワークに接続し、充電しているときに実行するサービスをスケジュールします。
public static final int MY_BACKGROUND_JOB = 0; ... public static void scheduleJob(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo job = new JobInfo.Builder( MY_BACKGROUND_JOB, new ComponentName(context, MyJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setRequiresCharging(true) .build(); js.schedule(job); }
ジョブの条件が満たされたとき、アプリはコールバックを受け取り、指定された {@code JobService.class} で {@link android.app.job.JobService#onStartJob onStartJob()} メソッドを実行します。 {@link android.app.job.JobScheduler} 実装の例については、JobScheduler サンプルアプリをご覧ください。
GMSCore サービスを使用し、Android 5.0(API レベル 21)以前をターゲットにしているアプリは、 {@code GcmNetworkManager} を使用して {@code Task.NETWORK_STATE_UNMETERED} を指定できます。
実行されているアプリは、登録された {@link android.content.BroadcastReceiver} を使用して {@code CONNECTIVITY_CHANGE} を引き続きリッスンできます。 ただし、{@link android.net.ConnectivityManager} API は、特定のネットワーク条件が満たされたときだけコールバックをリクエストするより堅牢なメソッドを提供します。
{@link android.net.NetworkRequest} オブジェクトは、{@link android.net.NetworkCapabilities} に応じてネットワーク コールバックのパラメータを定義します。 {@link android.net.NetworkRequest.Builder NetworkRequest.Builder} クラスを使って {@link android.net.NetworkRequest} オブジェクトを作成します。次に、{@link android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()} は、{@link android.net.NetworkRequest} オブジェクトをシステムに渡します。 ネットワーク条件が満たされると、アプリはコールバックを受け取り、{@link android.net.ConnectivityManager.NetworkCallback} クラスで定義された {@link android.net.ConnectivityManager.NetworkCallback#onAvailable onAvailable()} メソッドを実行します。
アプリは終了するか、{@link android.net.ConnectivityManager#unregisterNetworkCallback unregisterNetworkCallback()} を呼び出すまで、コールバックを受信し続けます。
Android N では、アプリは、{@link android.hardware.Camera#ACTION_NEW_PICTURE} ブロードキャストまたは {@link android.hardware.Camera#ACTION_NEW_VIDEO} ブロードキャストを送受信できません。この制限は、新しいイメージや動画を処理するためにいくつかのアプリを起動する必要があるときに、パフォーマンスとユーザー エクスペリエンスへの影響を軽減するのに役立ちます。 Android N では、{@link android.app.job.JobInfo} と {@link android.app.job.JobParameters} を拡張することにより、代わりのソリューションを提供しています。
Android N では、コンテンツ URI の変更でジョブをトリガーするために、{@link android.app.job.JobInfo} API に次のメソッドが追加されています。
注: {@code TriggerContentUri()} は、{@link android.app.job.JobInfo.Builder#setPeriodic setPeriodic()} または {@link android.app.job.JobInfo.Builder#setPersisted setPersisted()} と組み合わせて使うことはできません。 コンテンツの変更を継続的に監視するには、アプリの {@link android.app.job.JobService} が最新のコールバックの処理を完了する前に、新しい {@link android.app.job.JobInfo} をスケジュールします。
次のサンプルコードは、システムが変更をコンテンツ URI {@code MEDIA_URI} に通知するときにトリガーされるジョブをスケジュールします。
public static final int MY_BACKGROUND_JOB = 0; ... public static void scheduleJob(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo.Builder builder = new JobInfo.Builder( MY_BACKGROUND_JOB, new ComponentName(context, MediaContentJob.class)); builder.addTriggerContentUri( new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); js.schedule(builder.build()); }
システムが特定のコンテンツ URI の変更を通知すると、アプリはコールバックを受け取り、{@link android.app.job.JobParameters} オブジェクトが {@code MediaContentJob.class} の {@link android.app.job.JobService#onStartJob onStartJob()} メソッドに渡されます。
また、Android N では、{@link android.app.job.JobParameters} が拡張され、ジョブをトリガーしたコンテンツ権限や URI についての有用な情報をアプリが受け取れるようになっています。
次のサンプルコードは、{@link android.app.job.JobService#onStartJob JobService.onStartJob()} メソッドをオーバーライドし、ジョブを起動したコンテンツ権限と URI を記録します。
@Override public boolean onStartJob(JobParameters params) { StringBuilder sb = new StringBuilder(); sb.append("Media content has changed:\n"); if (params.getTriggeredContentAuthorities() != null) { sb.append("Authorities: "); boolean first = true; for (String auth : params.getTriggeredContentAuthorities()) { if (first) { first = false; } else { sb.append(", "); } sb.append(auth); } if (params.getTriggeredContentUris() != null) { for (Uri uri : params.getTriggeredContentUris()) { sb.append("\n"); sb.append(uri); } } } else { sb.append("(No content)"); } Log.i(TAG, sb.toString()); return true; }
アプリをメモリ不足の端末またはメモリ不足の状況で実行するために最適化すると、パフォーマンスとユーザー エクスペリエンスが向上します。 バックグラウンド サービスと静的に登録された暗黙的なブロードキャスト レシーバーへの依存関係を削除すると、そのような端末上のアプリの動作が向上します。 Android N では、これらの問題を削減するための措置が講じられていますが、これらのバックグラウンド処理をまったく使用せずに、アプリが実行されるように最適化することをお勧めします。
Android N には、それらのバックグラウンド処理を無効にした状態でアプリの動作をテストするために使用できるいくつかの Android Debug Bridge(ADB)コマンドが追加されています。
{@code $ adb shell cmd appops set <package> RUN_IN_BACKGROUND ignore}
{@code $ adb shell cmd appops set <package> RUN_IN_BACKGROUND allow}