page.title=Tối ưu hóa Chạy ngầm page.metaDescription=Các hạn chế mới đối với truyền phát không biểu thị. page.keywords="android N", "implicit broadcasts", "job scheduler" page.image=images/cards/card-nyc_2x.jpg @jd:body

Trong tài liệu này

  1. Các hạn chế về CONNECTIVITY_ACTION
  2. Lên lịch Tác vụ Mạng trên Kết nối Không đo lưu lượng
  3. Theo dõi Kết nối Mạng Trong khi Ứng dụng đang Chạy
  4. Các hạn chế về NEW_PICTURE và NEW_VIDEO
  5. Các phương thức JobInfo Mới
  6. Các phương thức JobParameter Mới
  7. Tối ưu hóa thêm Ứng dụng của bạn

Các tiến trình chạy ngầm có thể tiêu tốn bộ nhớ và pin. Ví dụ, một truyền phát không biểu thị có thể bắt đầu nhiều tiến trình chạy ngầm đã đăng ký để theo dõi chúng, ngay cả khi các tiến trình đó có thể không làm việc nhiều. Điều này có thể có ảnh hưởng lớn đến cả hiệu suất của thiết bị lẫn trải nghiệm của người dùng.

Để loại bỏ vấn đề này, N Developer Preview áp dụng các hạn chế sau:

Khuôn khổ Android cung cấp một số giải pháp để giảm thiểu sự cần thiết đối với các truyền phát không biểu thị. Ví dụ, {@link android.app.job.JobScheduler} và {@code GcmNetworkManager} cung cấp một cơ chế lên lịch hiệu quả cho các hoạt động mạng khi đáp ứng các điều kiện được chỉ định, ví dụ như kết nối tới mạng không đo lưu lượng. Bây giờ bạn cũng có thể sử dụng {@link android.app.job.JobScheduler} để phản ứng lại với các thay đổi đối với các trình cung cấp nội dung. Các đối tượng {@link android.app.job.JobInfo} gói gọn các tham số {@link android.app.job.JobScheduler} dùng để lên lịch tác vụ của bạn. Khi đáp ứng được các điều kiện của tác vụ, hệ thống sẽ thực thi tác vụ này trên {@link android.app.job.JobService} của ứng dụng của bạn.

Trong tài liệu này, chúng ta sẽ tìm hiểu cách sử dụng các phương thức thay thế, chẳng hạn như {@link android.app.job.JobScheduler}, để thích ứng ứng dụng của bạn với các hạn chế mới này.

Các hạn chế về CONNECTIVITY_ACTION

Các ứng dụng nhắm đến N Developer Preview không nhận được truyền phát {@link android.net.ConnectivityManager#CONNECTIVITY_ACTION} nếu chúng đăng ký nhận truyền phát trong bản kê khai của chúng, và các tiến trình phụ thuộc vào truyền phát này sẽ không khởi động. Điều này cũng đặt ra một vấn đề cho ứng dụng về việc theo dõi thay đổi mạng hoặc thực hiện các hoạt động mạng hàng loạt khi thiết bị kết nối với một mạng không đo lưu lượng. Một số giải pháp để tránh khỏi hạn chế này đã tồn tại trong khuôn khổ Android, nhưng chọn được một giải pháp phù hợp phụ thuộc vào những gì bạn muốn ứng dụng của bạn hoàn thành.

Lưu ý: Một{@link android.content.BroadcastReceiver} có đăng ký {@link android.content.Context#registerReceiver Context.registerReceiver()} tiếp tục nhận các truyền phát này trong khi ứng dụng đang ở tiền cảnh.

Lên lịch Tác vụ Mạng trên Kết nối Không đo lưu lượng

Khi sử dụng lớp{@link android.app.job.JobInfo.Builder JobInfo.Builder} để xây dựng đối tượng {@link android.app.job.JobInfo} của bạn, hãy áp dụng phương thức {@link android.app.job.JobInfo.Builder#setRequiredNetworkType setRequiredNetworkType()} và chuyển {@link android.app.job.JobInfo JobInfo.NETWORK_TYPE_UNMETERED} dưới dạng một tham số tác vụ. Đoạn mã mẫu sau lên lịch một dịch vụ để chạy khi thiết bị kết nối với một mạng không đo lưu lượng và đang sạc:

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

Khi các điều kiện cho tác vụ của bạn đã được đáp ứng, ứng dụng của bạn sẽ nhận được lệnh gọi lại để chạy phương thức{@link android.app.job.JobService#onStartJob onStartJob()}trong {@code JobService.class} được chỉ định. Để xem thêm các ví dụ về triển khai {@link android.app.job.JobScheduler} , hãy xem ứng dụng mẫu JobScheduler.

Các ứng dụng sử dụng dịch vụ GMSCore, và nhắm đến Android 5.0 (API mức 21) hoặc thấp hơn, có thể sử dụng {@code GcmNetworkManager} và quy định {@code Task.NETWORK_STATE_UNMETERED}.

Theo dõi Kết nối Mạng Trong khi Ứng dụng đang Chạy

Các ứng dụng đang chạy ở tiền cảnh vẫn có thể theo dõi {@code CONNECTIVITY_CHANGE} bằng một{@link android.content.BroadcastReceiver} đã đăng ký. Tuy nhiên, API {@link android.net.ConnectivityManager} cung cấp phương thức yêu cầu lệnh gọi lại hiệu quả hơn chỉ khi đáp ứng được các điều kiện được chỉ định.

Các đối tượng {@link android.net.NetworkRequest} định nghĩa các tham số của lệnh gọi lại mạng xét về {@link android.net.NetworkCapabilities}. Bạn tạo các đối tượng {@link android.net.NetworkRequest} bằng lớp {@link android.net.NetworkRequest.Builder NetworkRequest.Builder}. {@link android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()} rồi chuyển đối tượng{@link android.net.NetworkRequest} sang hệ thống. Khi đáp ứng được các điều kiện mạng, ứng dụng nhận lệnh gọi lại để thực thi phương thức {@link android.net.ConnectivityManager.NetworkCallback#onAvailable onAvailable()} như được định nghĩa trong lớp {@link android.net.ConnectivityManager.NetworkCallback} của nó.

Ứng dụng tiếp tục nhận lệnh gọi lại cho đến khi ứng dụng tồn tại hoặc nó gọi {@link android.net.ConnectivityManager#unregisterNetworkCallback unregisterNetworkCallback()}.

Các hạn chế về NEW_PICTURE và NEW_VIDEO

Trong N Developer Preview, ứng dụng không thể gửi hoặc nhận các truyền phát {@link android.hardware.Camera#ACTION_NEW_PICTURE} hoặc {@link android.hardware.Camera#ACTION_NEW_VIDEO}. Hạn chế này giúp loại bỏ các tác động về hiệu suất và trải nghiệm của người dùng khi một số ứng dụng phải thức dậy để xử lý một ảnh hoặc video mới. N Developer Preview mở rộng {@link android.app.job.JobInfo} và {@link android.app.job.JobParameters} để cung cấp một giải pháp thay thế.

Các phương thức JobInfo Mới

Để kích hoạt tác vụ khi thay đổi URI nội dung, N Developer Preview sẽ mở rộng API{@link android.app.job.JobInfo} bằng các phương thức sau:

{@code JobInfo.TriggerContentUri()}
Gói gọn các tham số yêu cầu để kích hoạt tác vụ khi thay đổi URI nội dung.
{@code JobInfo.Builder.addTriggerContentUri()}
Chuyển một đối tượng {@code TriggerContentUri} đến {@link android.app.job.JobInfo}. Một {@link android.database.ContentObserver} sẽ theo dõi URI nội dung được gói gọn. Nếu có nhiều đối tượng {@code TriggerContentUri} được liên kết với một tác vụ, hệ thống sẽ cung cấp lệnh gọi lại ngay cả khi hệ thống báo cáo có sự thay đổi chỉ ở trong một trong những URI nội dung.
Thêm cờ {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} để kích hoạt tác vụ nếu bất kỳ kế nhiệm nào của URI đã cho thay đổi. Cờ này tương ứng với tham số {@code notifyForDescendants} đã chuyển đến {@link android.content.ContentResolver#registerContentObserver registerContentObserver()}.

Lưu ý: {@code TriggerContentUri()} không thể được sử dụng kết hợp với {@link android.app.job.JobInfo.Builder#setPeriodic setPeriodic()} hoặc {@link android.app.job.JobInfo.Builder#setPersisted setPersisted()}. Để tiếp tục theo dõi các thay đổi nội dung, hãy lên lịch một {@link android.app.job.JobInfo} mới trước khi {@link android.app.job.JobService} của ứng dụng hoàn thành xử lý lệnh gọi lại gần đây nhất.

Đoạn mã mẫu sau lên lịch kích hoạt một tác vụ khi hệ thống báo cáo có sự thay đổi về URI nội dung, {@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(MEDIA_URI,
          JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
  js.schedule(builder.build());
}

Khi hệ thống báo cáo có sự thay đổi trong (các) URI nội dung được chỉ định, ứng dụng của bạn sẽ nhận được lệnh gọi lại và một đối tượng {@link android.app.job.JobParameters} được chuyển sang phương thức {@link android.app.job.JobService#onStartJob onStartJob()} trong {@code MediaContentJob.class}.

Các phương thức JobParameter Mới

N Developer Preview cũng mở rộng {@link android.app.job.JobParameters} để cho phép ứng dụng của bạn nhận thông tin hữu ích về những gì thẩm quyền nội dung và các URI đã kích hoạt tác vụ:

{@code Uri[] getTriggeredContentUris()}
Trả về mảng URI đã kích hoạt tác vụ đó. Kết quả trả về có thể bằng {@code null} nếu không có URI nào kích hoạt tác vụ (ví dụ như, tác vụ đã được kích hoạt do thời hạn hoặc lý do khác), hoặc số các URI bị thay đổi nhiều hơn 50.
{@code String[] getTriggeredContentAuthorities()}
Trả về mảng xâu thẩm quyền nội dung đã kích hoạt tác vụ đó. Nếu mảng được trả về không phải {@code null}, hãy dùng {@code getTriggeredContentUris()} để truy xuất chi tiết về URI nào đã thay đổi.

Mã mẫu sau sẽ ghi đè lên phương thức {@link android.app.job.JobService#onStartJob JobService.onStartJob()} và và ghi lại các thẩm quyền nội dung và URI đã kích hoạt tác vụ.

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

Tối ưu hóa thêm Ứng dụng của bạn

Tối ưu hóa ứng dụng của bạn để chạy trên các thiết bị có bộ nhớ ít, hoặc đang trong điều kiện bộ nhớ ít có thể cải thiện hiệu suất và trải nghiệm của người dùng. Loại bỏ các thành phần phụ thuộc trên các dịch vụ chạy ngầm và bộ thu truyền phát không biểu thị đã đăng ký tĩnh có thể giúp ứng dụng của bạn chạy tốt hơn trên các thiết bị như vậy. Mặc dù N Developer Preview thực hiện các bước để giảm bớt một vài trong số các vấn đề này, nhưng chúng tôi khuyến nghị bạn nên tối ưu ứng dụng của bạn để chạy hoàn toàn không cần sử dụng các tiến trình chạy ngầm này.

N Developer Preview giới thiệu một số lệnh Android Debug Bridge (ADB) bổ sung mà bạn có thể sử dụng để kiểm thử hành vi của ứng dụng bằng các tiến trình chạy ngầm đã bị vô hiệu hóa đó: