Di chuyển từ GCMNetworkManager sang WorkManager

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Tài liệu này giải thích cách di chuyển các ứng dụng để dùng thư viện ứng dụng WorkManager cho việc thực hiện hoạt động trong nền thay vì thư viện GCMNetworkManager. Ứng dụng thường dùng WorkManager để lên lịch công việc trong nền. Bằng cách thêm thư viện WorkManager GCM, WorkManager có thể dùng GCM để lên lịch tác vụ khi hoạt động trên thiết bị Android chạy API từ cấp 22 trở xuống.

Di chuyển sang WorkManager

Nếu ứng dụng của bạn hiện dùng GCMNetworkManager để thực hiện hoạt động trong nền, hãy làm theo các bước sau để di chuyển sang WorkManager.

Đối với các bước này, chúng tôi giả định bạn đang bắt đầu với mã GCMNetworkManager dùng để xác định và lên lịch tác vụ như sau:

Kotlin

val myTask = OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService::class.java)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(5 * DateUtil.MINUTE_IN_SECONDS,
            15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build()
GcmNetworkManager.getInstance(this).schedule(myTask)

Java

// In GcmNetworkManager, this call defines the task and its
// runtime constraints:
OneoffTask myTask = new OneoffTask.Builder()
    // setService() says what class does the work
    .setService(MyUploadService.class)
    // Don't run the task unless device is charging
    .setRequiresCharging(true)
    // Run the task between 5 & 15 minutes from now
    .setExecutionWindow(
        5 * DateUtil.MINUTE_IN_SECONDS,
        15 * DateUtil.MINUTE_IN_SECONDS)
    // Define a unique tag for the task
    .setTag("test-upload")
    // ...finally, build the task and assign its value to myTask
    .build();
GcmNetworkManager.getInstance(this).schedule(myTask);

Trong ví dụ này, chúng tôi giả định rằng MyUploadService sẽ xác định thao tác tải lên thực tế:

Kotlin

class MyUploadService : GcmTaskService() {
    fun onRunTask(params: TaskParams): Int {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS
    }
}

Java

class MyUploadService extends GcmTaskService {
    @Override
    public int onRunTask(TaskParams params) {
        // Do some upload work
        return GcmNetworkManager.RESULT_SUCCESS;
    }
}

Thêm các thư viện WorkManager

Để sử dụng các lớp WorkManager, bạn cần thêm thư viện WorkManager vào phần phụ thuộc của bản dựng. Bạn cũng cần thêm thư viện WorkManager GCM, nhờ đó WorkManager có thể dùng GCM để lên lịch công việc khi ứng dụng của bạn đang chạy trên thiết bị không hỗ trợ JobScheduler (tức là thiết bị chạy API từ cấp 22 trở xuống). Để nắm được đầy đủ thông tin chi tiết về cách thêm thư viện, hãy xem phần Bắt đầu sử dụng WorkManager.

Sửa đổi tệp kê khai

Khi triển khai GCMNetworkManager, bạn đã thêm một bản sao của GcmTaskService vào tệp kê khai ứng dụng, như đã mô tả trong tài liệu tham khảo về GcmNetworkManager . GcmTaskService sẽ xem xét những tác vụ sắp tới và giao tác vụ đó cho trình xử lý tác vụ. WorkManager quản lý tính năng uỷ quyền tác vụ cho Worker nên bạn không còn cần một lớp để thực hiện việc này; mà chỉ cần xoá GcmTaskService khỏi tệp kê khai.

Xác định Worker

Việc triển khai GCMNetworkManager sẽ xác định OneoffTask hoặc RecurringTask để chỉ xác định công việc cần làm. Bạn cần viết lại mã này dưới dạng Worker, như đã nêu trong phần Xác định yêu cầu công việc.

GCMNetworkManager mẫu xác định tác vụ trên myTask. Mã tương đương trong WorkManager có dạng như sau:

Kotlin

class UploadWorker(context: Context, params: WorkerParameters)
                        : Worker(context, params) {
    override fun doWork() : Result {
        // Do the upload operation ...
        myUploadOperation()

        // Indicate whether the task finished successfully with the Result
        return Result.success()
    }
}

Java

public class UploadWorker extends Worker {

    public UploadWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
      // Do the upload operation ...

      myUploadOperation()

      // Indicate whether the task finished successfully with the Result
      return Result.success()
    }
}

Có một vài điểm khác biệt giữa tác vụ GCM và Worker:

  • GCM dùng đối tượng TaskParams để chuyển tham số vào tác vụ. WorkManager sử dụng dữ liệu đầu vào mà bạn có thể chỉ định trên WorkRequest, như mô tả trong tài liệu về WorkManager để Xác định đầu vào/đầu ra của tác vụ. Trong cả hai trường hợp, bạn đều có thể chuyển các cặp giá trị/khoá nêu rõ mọi tham số liên tục cần thiết cho tác vụ.
  • GcmTaskService báo hiệu trạng thái thành công hoặc không thành công bằng cách trả về các cờ như GcmNetworkManager.RESULT_SUCCESS. Một WorkManager Worker báo hiệu kết quả bằng cách sử dụng phương thức ListenableWorker.Result, như ListenableWorker.Result.success(), và trả về giá trị mà phương thức trả lại.
  • Như chúng tôi đã đề cập, bạn không đặt quy tắc ràng buộc hoặc gắn thẻ khi xác định Worker. Thay vào đó, bạn sẽ thực hiện công việc này ở bước tiếp theo, khi tạo WorkRequest.

Lên lịch cho yêu cầu công việc

Việc xác định Worker sẽ nêu rõ những việc bạn cần làm. Để nêu rõ thời điểm phải hoàn thành công việc, bạn cần xác định WorkRequest:

  1. Tạo OneTimeWorkRequest hoặc PeriodicWorkRequest rồi đặt ra bất kỳ quy tắc ràng buộc nào mà bạn muốn chỉ định khi thực hiện tác vụ, cũng như bất kỳ thẻ nào để xác định công việc của bạn.
  2. Chuyển yêu cầu đến WorkManager.enqueue() để thêm tác vụ vào hàng đợi thực hiện.

Ví dụ: mục trước đã hướng dẫn cách chuyển đổi OneoffTask thành Worker tương đương. Tuy nhiên, Worker đó không bao gồm thẻ và quy tắc ràng buộc thực thi của đối tượng OneoffTask. Thay vào đó, chúng tôi sẽ đặt quy tắc ràng buộc và mã tác vụ khi tạo WorkRequest. Chúng tôi cũng sẽ nêu rõ để tác vụ không thực hiện nếu không có kết nối mạng. Bạn không cần đưa ra yêu cầu rõ ràng về việc GCMNetworkManager có kết nối mạng, vì theo mặc định, GCMNetworkManager phải có kết nối mạng, nhưng WorkManager không yêu cầu kết nối mạng trừ khi bạn thêm quy tắc cụ thể. Khi đã xác định được WorkRequest, chúng tôi sẽ thêm vào hàng đợi với WorkManager.

Kotlin

val uploadConstraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true).build()

val uploadTask = OneTimeWorkRequestBuilder<UploadWorker>()
    .setConstraints(uploadConstraints)
    .build()
WorkManager.getInstance().enqueue(uploadTask)

Java

Constraints uploadConstraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true)
    .build();

OneTimeWorkRequest uploadTask =
        new OneTimeWorkRequest.Builder(UploadWorker.class)
  .setConstraints(uploadConstraints)
  .build();
WorkManager.getInstance().enqueue(uploadTask);

Liên kết API

Phần này mô tả cách một số tính năng và quy tắc ràng buộc của GCMNetworkManager liên kết với tính năng và quy tắc tương đương của WorkManager.

Liên kết quy tắc ràng buộc

GCMNetworkManager cho phép bạn đặt ra một số quy tắc ràng buộc khi phải thực hiện tác vụ. Trong hầu hết các trường hợp, sẽ có quy tắc ràng buộc tương đương rõ ràng của WorkManager. Phần này nêu ra các quy tắc tương đương.

Đặt quy tắc ràng buộc cho những tác vụ trong GCMNetworkManager bằng cách gọi phương thức thích hợp trong đối tượng Builder của tác vụ. Ví dụ: bạn có thể đặt yêu cầu về mạng bằng cách gọi Task.Builder.setRequiredNetwork().

Trong WorkManager, bạn có thể tạo đối tượng của Constraints.Builder và gọi các phương thức của đối tượng đó để đặt những quy tắc ràng buộc (ví dụ: Constraints.Builder.setRequiredNetworkType())), sau đó sử dụng Builder để tạo đối tượng Constraints mà bạn có thể đính kèm vào yêu cầu công việc. Để biết thêm thông tin, hãy xem phần Xác định yêu cầu công việc.

Quy tắc ràng buộc trong GCMNetworkManager Quy tắc tương đương trong WorkManager Lưu ý
setPersisted() (không bắt buộc) Toàn bộ công việc trong WorkManager vẫn giữ nguyên sau khi khởi động lại thiết bị
setRequiredNetwork() setRequiredNetworkType() Theo mặc định, GCMNetworkManager cần có kết nối mạng. Theo mặc định, WorkManager không yêu cầu kết nối mạng. Nếu công việc của bạn yêu cầu kết nối mạng, bạn phải sử dụng setRequiredNetworkType(CONNECTED) hoặc cài đặt loại mạng cụ thể hơn.
setRequiresCharging()

Các cách liên kết khác

Ngoài các quy tắc ràng buộc, bạn còn có thể áp dụng các chế độ cài đặt khác cho tác vụ trong GCMNetworkManager. Phần này nêu ra các cách tương ứng để áp dụng những chế độ cài đặt đó cho công việc trong WorkManager.

Thẻ

Tất cả tác vụ trong GCMNetworkManager phải có một chuỗi thẻ mà bạn có thể đặt bằng cách gọi phương thức setTag() của Builder. WorkManager sẽ dùng các mã không trùng lặp để tự động xác định công việc trong WorkManager. Bạn có thể lấy những mã này bằng cách gọi WorkRequest.getId(). Ngoài ra, yêu cầu công việc có thể có một hoặc nhiều thẻ. Để đặt thẻ cho công việc trong WorkManager, hãy gọi phương thức WorkRequest.Builder.addTag(), trước khi bạn dùng Builder đó để tạo WorkRequest.

Trong GCMNetworkManager, bạn có thể gọi setUpdateCurrent() để nêu rõ xem tác vụ có phải thay thế mọi tác vụ hiện tại có cùng một thẻ hay không. Phương pháp tương đương trong WorkManager là thêm tác vụ vào hàng đợi bằng cách gọi enqueueUniqueWork() hoặc enqueueUniquePeriodicWork(); nếu dùng những phương thức này, bạn đặt một tên riêng cho công việc, đồng thời nêu rõ cách WorkManager giải quyết yêu cầu nếu đã có công việc mang tên giống như vậy đang chờ xử lý. Để biết thêm thông tin, hãy xem phần Xử lý công việc duy nhất.

Tham số của tác vụ

Bạn có thể chuyển tham số đến một công việc trong GCMNetworkManager bằng cách gọi Task.Builder.setExtras() và chuyển một Bundle chứa tham số đó. WorkManager cho phép bạn chuyển đối tượng trong Data đến công việc trong WorkManager, kèm theo các tham số như cặp giá trị/ khoá. Để biết thông tin chi tiết, hãy xem phần Chỉ định dữ liệu đầu vào.