WorkManager cho phép bạn cập nhật WorkRequest
sau khi đã đưa nó vào hàng đợi. Điều này thường cần thiết trong những ứng dụng lớn hơn, thường xuyên thay đổi các quy tắc ràng buộc hoặc cần cập nhật trình thực thi nhanh chóng. Kể từ WorkManager phiên bản 2.8.0, API updateWork()
sẽ 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 nhất định của
WorkRequest
một cách nhanh chóng mà không phải thực hiện quy trình huỷ và thêm một chế độ mới theo cách thủ công. Việc này giúp đơn giản hoá đáng kể quá trình phát triển.
Tránh huỷ công việc
Thường thì bạn không nên huỷ một WorkRequest hiện có và thêm một WorkRequest mới. Làm như vậy có thể khiến ứng dụng lặp lại một số tác vụ và có thể yêu cầu bạn viết một lượng đáng kể mã bổ sung.
Hãy xem các ví dụ sau đây về trường hợp huỷ WorkRequest có thể gây ra khó khăn:
- Yêu cầu phụ trợ: Nếu bạn huỷ một
Worker
trong khi đang tính toán tải trọng để gửi đến máy chủ, thìWorker
mới cần phải bắt đầu lại và tính toán lại tải trọng có thể gây tốn kém. - Lên lịch: Nếu huỷ
PeriodicWorkRequest
và muốnPeriodicWorkRequest
mới thực thi trên cùng lịch biểu, thì bạn cần tính toán mức chênh lệch thời gian để đảm bảo thời gian thực thi mới phù hợp 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 quy tắc 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 vấn đề gì khi huỷ và thêm một yêu cầu mới vào hàng đợi.
Thời điểm 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 việc bạn nên làm khi muốn thay đổi tính chất cơ bản của tác vụ mà bạn đã đưa vào hàng đợi.
Thời điểm cập nhật công việc
Hãy tưởng tượng một ứng dụng ảnh thực hiện việc sao lưu ảnh của người dùng hằng ngày. Thiết bị đã thêm PeriodicWorkRequest
vào hàng đợi để thực hiện việc này. WorkRequest
có các hạn chế yêu cầu thiết bị phải sạc và kết nối với Wi-Fi.
Tuy nhiên, người dùng chỉ sạc thiết bị của họ trong 20 phút mỗi ngày bằng bộ sạc nhanh. Trong trường hợp này, ứng dụng nên cập nhật WorkRequest
để nới lỏng giới hạn sạc, nhờ đó ứng dụng 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ác quy tắc ràng buộc của yêu cầu công việc.
Cách cập nhật công việc
Phương thức updateWork()
cung cấp một phương thức đơn giản để cập nhật
WorkRequest
hiện có mà không cần huỷ và thêm một phương thức mới vào hàng đợi.
Để sử dụng tác vụ cập nhật trong hàng đợi, hãy làm theo các bước sau:
- 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 cập nhật. Bạn có thể truy xuất mã nhận dạng này bằng bất kỳ API
getWorkInfo
nào hoặc bằng cách duy trì mã đó theo cách thủ công từ WorkRequest ban đầu để truy xuất sau này bằng thuộc tính công khaiWorkRequest.id
trước khi thêm vào hàng đợi. - Tạo WorkRequest mới: Tạo một
WorkRequest
mới và sử dụngWorkRequest.Builder.setID()
để đặt mã nhận dạng cho khớp với mã củaWorkRequest
hiện có. - Đặt điều kiện ràng buộc: Sử dụng
WorkRequest.Builder.setConstraints()
để truyền các quy tắc ràng buộc mới cho WorkManager. - Gọi updateWork: Truyền WorkRequest mới đến
updateWork()
.
Ví dụ về cập nhật công việc
Dưới đây là một đ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
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ề một ListenableFuture<UpdateResult>
. UpdateResult
đã cho có thể có một trong vài giá trị nêu rõ việc WorkManager có thể áp dụng các thay đổi của bạn hay không. Cột này cũng cho biết thời điểm có thể áp dụng thay đổi.
Để biết thêm thông tin, hãy xem updateWork()
và 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 một WorkRequest
, quá trình tạo sẽ tăng thêm 1. Việc này cho phép bạn theo dõi chính xác WorkRequest
hiện đang được đưa vào hàng đợi.
Thế hệ cung cấp cho bạn nhiều quyền kiểm soát hơn khi quan sát, theo dõi và kiểm thử các yêu cầu công việc.
Để tạo WorkRequest
, hãy làm theo các bước sau:
- WorkInfo: Gọi
WorkManager.getWorkInfoById()
để truy xuất một thực thể củaWorkInfo
tương ứng vớiWorkRequest
của bạn.- Bạn có thể gọi một trong nhiều phương thức trả về
WorkInfo
. Để biết thêm thông tin, hãy xem tài liệu tham khảo về WorkManager.
- Bạn có thể gọi một trong nhiều phương thức trả về
- getGeneration: Gọi
getGeneration()
trên thực thể củaWorkInfo
.Int
được trả về tương ứng với quá trình tạoWorkRequest
.- Lưu ý rằng không có trường hoặc thuộc tính tạo, chỉ có phương thức
WorkInfo.getGeneration()
.
- Lưu ý rằng không có trường hoặc thuộc tính tạo, chỉ có phương thức
Ví dụ về cách 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 để truy xuất quá trình 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 đề xuất để cập nhật công việc định kỳ là thêm PeriodicWorkRequest
vào hàng đợi theo chính sách ExistingPeriodicWorkPolicy.REPLACE
.
Nếu có một PeriodicWorkRequest
đang chờ xử lý có cùng id
duy nhất, thì yêu cầu công việc mới sẽ huỷ và xoá yêu cầu đó. Chính sách này hiện không được dùng nữa và được thay thế bằng quy trình sử dụng ExistingPeriodicWorkPolicy.UPDATE
.
Ví dụ: khi sử dụng enqueueUniquePeriodicWork
với PeriodicWorkRequest
, bạn có thể khởi chạy PeriodicWorkRequest
mới bằng chính sách ExistingPeriodicWorkPolicy.UPDATE
. Nếu có một PeriodicWorkRequest
đang chờ xử lý có cùng tên duy nhất, WorkManager sẽ cập nhật thành quy cách mới. Theo quy trình công việc này, bạn không cần sử dụng updateWork()
.