LoginSignup
7
5

More than 5 years have passed since last update.

[翻訳] Android N PreviewのBackground Optimizations

Last updated at Posted at 2016-03-17

Android N PreviewのBackground Optimizationsを翻訳してみました。

おかしな部分があればコメント頂ければと思います。

以下、関連する投稿へのリンクです。
■ Android N PreviewのBehavior Changes 公式 翻訳
Android N PreviewのBackground Optimizations 公式 翻訳
■ Android N PreviewのAPIの概要 公式 翻訳

注)この内容はPreview1時点のものです。
  最新版とは差分が発生している可能性があります。

公式が翻訳されました ので、公式をご覧ください。 m(_ _)m

Background Optimizations

Background processes can be memory- and battery-intensive. For example, an implicit broadcast may start many background processes that have registered to listen for it, even if those processes may not do much work. This can have a substantial impact on both device performance and user experience.

To alleviate this issue, the N Developer Preview applies the following restrictions:

If your app uses any of these intents, you should remove dependencies on them as soon as possible so that you can target Android N devices properly. The Android framework provides several solutions to mitigate the need for these implicit broadcasts. For example, JobScheduler and GcmNetworkManager provide robust mechanisms to schedule network operations when specified conditions, such as a connection to an unmetered network, are met. You can now also use JobScheduler to react to changes to content providers. JobInfo objects encapsulate the parameters that JobScheduler uses to schedule your job. When the conditions of the job are met, the system executes this job on your app's JobService.

In this document, we will learn how to use alternative methods, such as JobScheduler, to adapt your app to these new restrictions.

バックグラウンドプロセスは、メモリととバッテリーを大量に消費する場合があります。 例えば暗黙のブロードキャストは、それをリッスンするよう登録されている多くのバックグラウンドプロセスを、たとえそれらのプロセスがたいした処理をしないとしても起動するでしょう。 これはデバイスのパフォーマンスとユーザーエクスペリエンスの双方に大きな影響を与える可能性があります。

この問題を軽減するために、N Developer Previewは、次の制限を適用します:

  • プレビューを対象にしたアプリは、マニフェストで受信登録をしても、CONNECTIVITY_ACTIONブロードキャストを受信しません。 フォアグラウンドで実行中のアプリは今後もContext.registerReceiver()BroadcastReceiverを登録することにより、メインスレッドでCONNECTIVITY_CHANGEをリッスンできます。

  • アプリはACTION_NEW_PICTUREまたはACTION_NEW_VIDEOブロードキャストを、送信または受信できません。 この最適化はプレビューを対象にしたアプリだけでなく、すべてのアプリに影響します。

あなたのアプリがこれらのインテントのいずれかを使用している場合、適切にAndroid Nを対象とするために、それらへの依存をできるだけ早く取り除くべきです。 Androidフレームワークは、これらの暗黙のブロードキャストの必要性を軽減させるため、いくつかの解決方法を提供します。 例えば、JobSchedulerGcmNetworkManagerは、定額ネットワークへの接続のような特定の条件下でのネットワーク操作をスケジュールするための、強力な仕組みを提供します。 またJobSchedulerを、コンテンツプロバイダの変更に対応するためにも使用できます。 JobInfoオブジェクトはJobSchedulerがあなたのジョブをスケジュールするために使用するパラメータをカプセル化します。 ジョブの条件が満たされると、システムはアプリのJobServiceでこのジョブを実行します。

このドキュメントでは、これらの新しい制限にアプリを適応させるために、JobSchedulerのような代替メソッドの使い方を学びます。

Restrictions on CONNECTIVITY_ACTION

Apps targeting the N Developer Preview do not receive CONNECTIVITY_ACTION broadcasts if they register to receive them in their manifest, and processes that depend on this broadcast will not start. This could pose a problem for apps that want to listen for network changes or perform bulk network activities when the device connects to an unmetered network. Several solutions to get around this restriction already exist in the Android framework, but choosing the right one depends on what you want your app to accomplish.

Note: A BroadcastReceiver registered with Context.registerReceiver() continues to receive these broadcasts while the app is in the foreground.

N Developer Previewを対象にしたアプリは、マニフェストで受信登録をしても、CONNECTIVITY_ACTIONブロードキャストを受信しません。 そして、このブロードキャストに依存したプロセスは起動しません。

これはネットワークの変更をリッスンしたい、またはデバイスが定額ネットワークに接続したときにまとめてネットワーク処理したいアプリにとって問題を起こす可能性があります。

Androidフレームワークには、この制限を回避するためのいくつかの解決方法がすでにあります。 あなたがアプリでやりたいことを元に、適切な一つを選択します。

Context.registerReceiver()で登録されたBroadcastReceiverは、アプリがフォアグラウンドにいる間は、これらのブロードキャストを受信し続けます。

Scheduling Network Jobs on Unmetered Connections

When using the JobInfo.Builder class to build your JobInfo object, apply the setRequiredNetworkType() method and pass JobInfo.NETWORK_TYPE_UNMETERED as a job parameter. The following code sample schedules a service to run when the device connects to an unmetered network and is charging:

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);
}

When the conditions for your job are met, your app receives a callback to run the onStartJob() method in the specified JobService.class. To see more examples of JobScheduler implementation, see the JobScheduler sample app.

Applications that use GMSCore services, and target Android 5.0 (API level 21) or lower, can use GcmNetworkManager and specify Task.NETWORK_STATE_UNMETERED.

JobInfoオブジェクトを構築するためにJobInfo.Builderを使用するときは、setRequiredNetworkType()を適用し、ジョブパラメータとして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);
}

あなたのジョブの条件が満たされたとき、あなたのアプリは指定されたJobService.classonStartJob()を実行するコールバックを受け取ります。 JobScheduler実装のより多くの例を見るには、JobScheduler sample appを参照してください。

GMSCoreサービスを使用し、Android 5.0 (API level 21)以下を対象としているアプリは、GcmNetworkManagerを使用してTask.NETWORK_STATE_UNMETEREDを指定できます。

Monitoring Network Connectivity While the App is Running

Apps running in the foreground can still listen for CONNECTIVITY_CHANGE with a registered BroadcastReceiver. However, the ConnectivityManager API provides a more robust method to request a callback only when specified network conditions are met.

NetworkRequest objects define the parameters of the network callback in terms of NetworkCapabilities. You create NetworkRequest objects with the NetworkRequest.Builder class. registerNetworkCallback() then passes the NetworkRequest object to the system. When the network conditions are met, the app receives a callback to execute the onAvailable() method defined in its ConnectivityManager.NetworkCallback class.

The app continues to receive callbacks until either the app exits or it calls unregisterNetworkCallback().

フォアグラウンドで実行されているアプリは、今後も登録したBroadcastReceiverCONNECTIVITY_CHANGEをリッスンできます。 しかしConnectivityManager APIは、特定のネットワーク条件を満たすときだけコールバックを要求するための、より強力なメソッドを提供します。

NetworkRequestオブジェクトは、NetworkCapabilitiesの点からネットワークのコールバックのパラメータを定義します。 NetworkRequest.Builderクラスを使用してNetworkRequestオブジェクトを作成します。 registerNetworkCallback()NetworkRequestオブジェクトをシステムに渡します。 ネットワーク条件が満たされると、アプリはConnectivityManager.NetworkCallbackクラスで定義されたonAvailable()メソッドを実行するコールバックを受け取ります。

アプリは終了するか、またはunregisterNetworkCallback()を呼び出すまでコールバックを受信し続けます。

Restrictions on NEW_PICTURE and NEW_VIDEO

In the N Developer Preview, apps are not able to send or receive ACTION_NEW_PICTURE or ACTION_NEW_VIDEO broadcasts. This restriction helps alleviate the performance and user experience impacts when several apps must wake up in order to process a new image or video. The N Developer Preview extends JobInfo and JobParameters to provide an alternative solution.

N Developer Previewでは、アプリはACTION_NEW_PICTUREACTION_NEW_VIDEOブロードキャストを送信または受信できません。 この制限は、いくつかのアプリが新しい画像やビデオを処理するために起動しないといけないとき、パフォーマンスおよびユーザーエクスペリエンスへの影響を軽減するのに役立ちます。 N Developer Previewは代わりの解決方法を提供するために、JobInfoJobParametersを拡張します。

New JobInfo methods

To trigger jobs on content URI changes, the N Developer Preview extends the JobInfo API with the following methods:

JobInfo.TriggerContentUri()

Encapsulates parameters required to trigger a job on content URI changes.

JobInfo.Builder.addTriggerContentUri()

Passes a TriggerContentUri object to JobInfo. A ContentObserver monitors the encapsulated content URI. If there are multiple TriggerContentUri objects associated with a job, the system provides a callback even if it reports a change in only one of the content URIs.

Add the TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS flag to trigger the job if any descendants of the given URI change. This flag corresponds to the notifyForDescendants parameter passed to registerContentObserver().

Note: TriggerContentUri() cannot be used in combination with setPeriodic() or setPersisted(). To continually monitor for content changes, schedule a new JobInfo before the app’s JobService finishes handling the most recent callback.

The following sample code schedules a job to trigger when the system reports a change to the content URI, 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(MEDIA_URI,
          JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
  js.schedule(builder.build());
}

When the system reports a change in the specified content URI(s), your app receives a callback and a JobParameters object is passed to the onStartJob() method in MediaContentJob.class.

content URIの変更でジョブを起動するため、N Developer PreviewはJobInfo APIに次のメソッドを追加します:

JobInfo.TriggerContentUri()

content URIの変更でジョブを起動するために必要なパラメータをカプセル化します。

JobInfo.Builder.addTriggerContentUri()

JobInfoTriggerContentUriオブジェクトを渡します。 ContentObserverは、カプセル化されたcontent URIを監視します。 ジョブに関連する複数のTriggerContentUriオブジェクトがある場合、システムはcontent URIのうちの一つのみの変更の通知であっても、コールバックを行います。

指定したURIの子孫のいずれかに変更があった場合にジョブを起動するためには、TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTSフラグを追加します。 このフラグはregisterContentObserver()に渡すnotifyForDescendantsに相当します。

注意TriggerContentUri()setPeriodic()またはsetPersisted()と組み合わせて使うことはできません。 content変更を継続的に監視するには、アプリのJobServiceが最新のコールバックの処理を終える前に、新しいJobInfoをスケジュールします。

次のサンプルコードは、システムがcontent URI(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(MEDIA_URI,
          JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
  js.schedule(builder.build());
}

システムが特定のcontent URIの変更を通知するとき、アプリはコールバックを受け取り、JobParametersオブジェクトがMediaContentJob.classonStartJob()メソッドに渡されます。

New JobParameter Methods

The N Developer Preview also extends JobParameters to allow your app to receive useful information about what content authorities and URIs triggered the job:

Uri[] getTriggeredContentUris()

Returns an array of URIs that have triggered the job. This will be null if either no URIs have triggered the job (for example, the job was triggered due to a deadline or some other reason), or the number of changed URIs is greater than 50.

String[] getTriggeredContentAuthorities()

Returns a string array of content authorities that have triggered the job. If the returned array is not null, use getTriggeredContentUris() to retrieve the details of which URIs have changed.

The following sample code overrides the JobService.onStartJob() method and records the content authorities and URIs that have triggered the job:

@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はジョブを起動したcontent authoritiesとURIsがなにかについて、あなたが有益な情報を受け取れるように、JobParametersを拡張します:

Uri[] getTriggeredContentUris()

ジョブを起動したURIsの配列を返します。 これはジョブを起動したURIsが無い場合 (例えばジョブが期限切れまたはその他の理由で起動した)、または変更されたURIの数が50を超える場合には、nullになります。

String[] getTriggeredContentAuthorities()

ジョブを起動したcontent authoritiesの配列を返します。 返された配列がnullでない場合、どのURIsが変更されたかの詳細を取得するために、getTriggeredContentUris()を使用します。

次のコード例では、JobService.onStartJob()をオーバーライドし、ジョブを起動したcontent authoritiesとURIsを記録します。

@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;
}

Further Optimizing Your App

Optimizing your apps to run on low-memory devices, or in low-memory conditions, can improve performance and user experience. Removing dependencies on background services and statically-registered implicit broadcast receivers can help your app run better on such devices. Although the N Developer Preview takes steps to reduce some of these issues, it is recommended that you optimize your app to run without the use of these background processes entirely.

The N Developer Preview introduces some additional Android Debug Bridge (ADB) commands that you can use to test app behavior with those background processes disabled:

  • To simulate conditions where implicit broadcasts and background services are unavailable, enter the following command:
$ adb shell cmd appops set RUN_IN_BACKGROUND ignore
  • To re-enable implicit broadcasts and background services, enter the following command:
$ adb shell cmd appops set RUN_IN_BACKGROUND allow

あなたのアプリを、メモリの少ないデバイス上またはメモリ不足の状況下での実行に最適化することで、パフォーマンスとユーザーエクスペリエンスを向上できます。 バックグラウンドサービスと静的に登録された暗黙のブロードキャストレシーバーへの依存の除去は、そのようなデバイスであなたのアプリを実行するのに役立ちます。 Android Nはこれらの問題のいくつかを減らすためにステップを要しますが、あなたのアプリをこれらのバックグラウンドプロセスを一切使用せずに実行するよう最適化することをお勧めします。

Android Nは、そのようなバックグラウンドプロセスが無効な状況でのアプリの動作をテストするために使用できるいくつかの追加のAndroid Debug Bridge (ADB)コマンドを導入します。

  • 暗黙のブロードキャストとバックグラウンドサービスが利用できない条件をシミュレートするには、次のコマンドを入力します。

    $ adb shell cmd appops set RUN_IN_BACKGROUND ignore
    
  • 暗黙のブロードキャストとバックグラウンドサービスを再度有効にするには、次のコマンドを入力します。

    $ adb shell cmd appops set RUN_IN_BACKGROUND allow
    
7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5