page.title=백그라운드 최적화 page.metaDescription=암시적 브로드캐스트에 대한 새로운 제한. page.keywords="android N", "implicit broadcasts", "job scheduler" page.image=images/cards/card-nyc_2x.jpg @jd:body

이 문서의 내용

  1. CONNECTIVITY_ACTION에 대한 제한
  2. 무제한 연결에서 네트워크 작업 예약
  3. 앱이 실행되는 중에 네트워크 연결 모니터링
  4. NEW_PICTURE 및 NEW_VIDEO에 대한 제한
  5. 새로운 JobInfo 메서드
  6. 새로운 JobParameter 메서드
  7. 추가적인 앱 최적화

백그라운드 프로세스는 메모리와 배터리를 많이 소모할 수 있습니다. 예를 들어, 암시적 브로드캐스트는 이 브로드캐스트를 수신하도록 등록된 많은 백그라운드 프로세스를 시작할 수 있지만 해당 프로세스가 많은 작업을 수행하지 못할 경우가 있습니다. 이로 인해 기기 성능과 사용자 환경에 모두 상당한 영향을 미칠 수 있습니다.

이 문제를 완화하기 위해, 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})를 사용하여 이러한 새로운 제한에 맞게 앱을 적용하는 방법에 대해 배워보겠습니다.

CONNECTIVITY_ACTION에 대한 제한

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.Builder JobInfo.Builder} 클래스를 사용하여 {@link android.app.job.JobInfo} 객체를 빌드하는 경우, {@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);
}

작업의 조건이 충족되면, 앱은 {@link android.app.job.JobService#onStartJob onStartJob()} 메서드를 지정된 {@code JobService.class}에서 실행하기 위한 콜백을 수신합니다. {@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()}을 호출할 때까지 계속해서 콜백을 수신합니다.

NEW_PICTURE 및 NEW_VIDEO에 대한 제한

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}를 확장하여 대체 해결책을 제공합니다.

새로운 JobInfo 메서드

콘텐츠 URI 변경에 대한 작업을 트리거하기 위해, Android N은 다음과 같은 메서드로 {@link android.app.job.JobInfo} API를 확장합니다.

{@code JobInfo.TriggerContentUri()}
콘텐츠 URI 변경에 대한 작업을 트리거하는 데 필요한 매개변수를 캡슐화합니다.
{@code JobInfo.Builder.addTriggerContentUri()}
{@code TriggerContentUri} 객체를 {@link android.app.job.JobInfo}에 전달합니다. {@link android.database.ContentObserver}는 캡슐화된 콘텐츠 URI를 모니터링합니다. 하나의 작업과 연관된 여러 {@code TriggerContentUri} 객체가 있는 경우, 콘텐츠 URI 중 하나에서만 변경이 보고되더라도 시스템이 콜백을 제공합니다.
지정된 URI의 하위 항목이 하나라도 변경되면, {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} 플래그를 추가하여 작업을 트리거합니다. 이 플래그는 {@link android.content.ContentResolver#registerContentObserver registerContentObserver()}로 전달된 {@code notifyForDescendants} 매개변수에 해당합니다.

참고: {@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()}메서드에 전달됩니다.

새로운 JobParameter 메서드

또한, Android N에서는 어떤 콘텐츠 기관과 URI가 해당 작업을 트리거했는지에 대한 유용한 정보를 앱이 수신할 수 있도록 {@link android.app.job.JobParameters}를 확장합니다.

{@code Uri[] getTriggeredContentUris()}
작업을 트리거한 URI의 배열을 반환합니다. 작업을 트리거한 URI가 없거나(예: 시한 또는 기타 이유로 인해 작업이 트리거된 경우) 또는 변경된 URI의 수가 50보다 크면 {@code null}이 됩니다.
{@code String[] getTriggeredContentAuthorities()}
작업을 트리거한 콘텐츠 기관의 문자열 배열을 반환합니다. 반환된 배열이 {@code null}이 아닌 경우, {@code getTriggeredContentUris()}를 사용하여 변경된 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에서는 백그라운드 프로세스를 비활성화하고 앱 동작을 테스트하는 데 사용할 수 있는 몇 가지 추가적인 ADB(Android 디버그 브리지) 명령을 도입했습니다.