Cập nhật tác vụ đã được thêm vào hàng đợi

WorkManager cho phép bạn cập nhật WorkRequest sau khi đã đã thêm mục đó vào hàng đợi. Điều này thường cần thiết trong các ứng dụng lớn hơn và thường xuyên thay đổi hạn chế hoặc cần cập nhật nhanh trình thực thi. Kể từ WorkManager phiên bản 2.8.0, API updateWork() là phương tiện để thực hiện việc này.

Phương thức updateWork() cho phép bạn thay đổi một số khía cạnh của WorkRequest một cách nhanh chóng mà không cần phải thực hiện quy trình xác minh theo cách thủ công đang huỷ và thêm một yêu cầu mới vào hàng đợi. Điều này giúp đơn giản hoá đáng kể quá trình phát triển của chúng tôi.

Tránh huỷ công việc

Thường thì bạn nên tránh huỷ một WorkRequest hiện có và thêm một WorkRequest mới vào hàng đợi một. Nếu bạn làm như vậy, ứng dụng có thể phải lặp lại một số thao tác và bạn có thể phải làm một số việc như vậy phải viết một lượng lớn mã bổ sung.

Hãy xem xét các ví dụ sau đây về nguyên nhân gây ra việc huỷ WorkRequest khó khăn:

  • Yêu cầu phụ trợ: Nếu bạn huỷ một Worker trong khi hệ thống đang tính toán một tải trọng cần gửi đến máy chủ, Worker mới cần bắt đầu lại và tính toán lại tải trọng có thể tốn kém.
  • Lên lịch: Nếu bạn huỷ một PeriodicWorkRequest rồi như PeriodicWorkRequest mới để thực thi theo cùng một lịch biểu, bạn cần để tính toán chênh lệch thời gian nhằm đảm bảo rằng thời gian thực thi mới được căn chỉnh với yêu cầu công việc trước đó.

API updateWork() cho phép bạn cập nhật các điều kiện ràng buộc của yêu cầu công việc và các tham số khác mà không gặp rắc rối khi huỷ và xếp hàng yêu cầu mới vào hàng đợi.

Trường hợp huỷ công việc

Có những trường hợp bạn nên trực tiếp huỷ WorkRequest thay vì gọi updateWork(). Đây là những gì bạn nên làm khi muốn thay đổi tính chất cơ bản của công việc mà bạn đã thêm vào hàng đợi.

Thời điểm cập nhật thông tin công việc

Hãy tưởng tượng một ứng dụng ảnh thực hiện sao lưu ảnh của người dùng hằng ngày. Có thêm một PeriodicWorkRequest vào hàng đợi để thực hiện việc này. WorkRequest có các quy tắc ràng buộc yêu cầu thiết bị đang sạc và kết nối với Wi-Fi.

Tuy nhiên, người dùng chỉ sạc thiết bị 20 phút mỗi ngày bằng bộ sạc. Trong trường hợp này, ứng dụng nên cập nhật WorkRequest để giảm thời gian hạn chế sạc, do đó thiết bị vẫn có thể tải ảnh lên ngay cả khi thiết bị chưa được sạc đầy.

Trong trường hợp này, bạn có thể sử dụng phương thức updateWork() để cập nhật công việc các hạn chế của yêu cầu.

Cách cập nhật công việc

Phương thức updateWork() cung cấp một phương tiện đơn giản để cập nhật dữ liệu hiện có WorkRequest mà không phải huỷ và thêm một mã mới vào hàng đợi.

Để sử dụng bản cập nhật công việc trong hàng đợi, hãy làm theo các bước sau:

  1. Lấy mã nhận dạng hiện có cho công việc trong hàng đợi: Lấy mã nhận dạng của WorkRequest mà bạn muốn muốn cập nhật. Bạn có thể truy xuất ID này bằng bất kỳ Các API getWorkInfo hoặc bằng cách duy trì mã nhận dạng từ ban đầu theo cách thủ công WorkRequest để truy xuất sau bằng thuộc tính công khai WorkRequest.id, trước khi thêm vào hàng đợi.
  2. Tạo WorkRequest mới: Tạo một WorkRequest mới rồi sử dụng WorkRequest.Builder.setID() để đặt mã nhận dạng khớp với mã của mã nhận dạng hiện có WorkRequest.
  3. Thiết lập quy tắc ràng buộc: Sử dụng WorkRequest.Builder.setConstraints() để truyền giá trị Các quy tắc ràng buộc mới của WorkManager.
  4. Gọi updateWork: Truyền WorkRequest mới cho updateWork().

Ví dụ về cập nhật công việc

Dưới đây là đoạn mã mẫu trong Kotlin minh hoạ cách sử dụng Phương thức updateWork() để thay đổi các giới hạn pin của WorkRequest được sử dụng để tải ảnh lên:

suspend fun updatePhotoUploadWork() {
    // Get instance of WorkManager.
    val workManager = WorkManager.getInstance(context)

    // Retrieve the work request ID. In this example, the work being updated is unique
    // work so we can retrieve the ID using the unique work name.
    val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
        PHOTO_UPLOAD_WORK_NAME
    ).await()

    val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return

    // Update the constraints of the WorkRequest to not require a charging device.
    val newConstraints = Constraints.Builder()
        // Add other constraints as required here.
        .setRequiresCharging(false)
        .build()

    // Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
    val updatedWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<MyWorker>()
            .setConstraints(newConstraints)
            .setId(existingWorkRequestId)
            .build()

    // Pass the new WorkRequest to updateWork().
    workManager.updateWork(updatedWorkRequest)
}

Xử lý kết quả

updateWork() trả về ListenableFuture<UpdateResult>. Biến thể đã cho UpdateResult có thể có một trong vài giá trị cho biết liệu có WorkManager đã áp dụng các thay đổi của bạn. Thông tin này cũng cho biết thời điểm có thể để áp dụng nội dung thay đổi.

Để biết thêm thông tin, hãy xem updateWork() UpdateResult tài liệu tham khảo.

Theo dõi công việc bằng nhiều thế hệ

Mỗi lần bạn cập nhật WorkRequest, thế hệ của mã này sẽ tăng thêm 1. Chiến dịch này cho phép bạn theo dõi chính xác WorkRequest nào đang được thêm vào hàng đợi. Tính năng tạo giúp bạn có nhiều quyền kiểm soát hơn khi quan sát, theo dõi và kiểm thử công việc yêu cầu.

Để tạo WorkRequest, hãy làm theo các bước sau:

  1. WorkInfo: Gọi WorkManager.getWorkInfoById() để truy xuất một thực thể WorkInfo tương ứng với WorkRequest của bạn.
  2. getGeneration: Gọi getGeneration() trên thực thể của WorkInfo. Int được trả về tương ứng với việc tạo WorkRequest
    • Xin lưu ý rằng không có trường hoặc thuộc tính tạo, mà chỉ có trường WorkInfo.getGeneration().

Ví dụ về quá trình tạo kênh

Sau đây là ví dụ về cách triển khai quy trình công việc được mô tả ở trên cho truy xuất hoạt động tạo WorkRequest.

// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)

// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)

// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()

Chính sách cập nhật công việc

Trước đây, giải pháp được đề xuất để cập nhật công việc định kỳ là thêm một PeriodicWorkRequest với chính sách ExistingPeriodicWorkPolicy.REPLACE. Nếu có một PeriodicWorkRequest đang chờ xử lý với cùng một id duy nhất, thì yêu cầu công việc sẽ huỷ và xoá nó. Chính sách này hiện không còn được dùng trong ưu tiên của quy trình làm việc bằng cách sử dụng ExistingPeriodicWorkPolicy.UPDATE.

Ví dụ: khi sử dụng enqueueUniquePeriodicWork với một PeriodicWorkRequest, bạn có thể khởi chạy PeriodicWorkRequest mới bằng ExistingPeriodicWorkPolicy.UPDATE. Nếu có một yêu cầu PeriodicWorkRequest có cùng tên riêng biệt, WorkManager sẽ cập nhật thành thông số kỹ thuật mới. Khi làm theo quy trình này, bạn không cần sử dụng updateWork().