Tạo chuỗi công việc

WorkManager cho phép bạn tạo và sắp xếp chuỗi công việc gồm nhiều tác vụ phụ thuộc và xác định thứ tự thực hiện. Chức năng này đặc biệt hữu ích khi bạn cần thực hiện nhiều tác vụ theo thứ tự cụ thể.

Để tạo chuỗi công việc, bạn có thể dùng WorkManager.beginWith(OneTimeWorkRequest) hoặc WorkManager.beginWith(List<OneTimeWorkRequest>). Mỗi phương thức đều trả về một đối tượng thuộc WorkContinuation.

Sau đó, có thể dùng WorkContinuation để thêm đối tượng OneTimeWorkRequest phụ thuộc bằng cách sử dụng then(OneTimeWorkRequest) hoặc then(List<OneTimeWorkRequest>) .

Mỗi lần gọi WorkContinuation.then(...) sẽ trả về một đối tượng WorkContinuation mới. Nếu thêm List các đối tượng OneTimeWorkRequest, bạn có thể thực hiện song song những yêu cầu này.

Cuối cùng, bạn có thể dùng phương thức WorkContinuation.enqueue() để enqueue() chuỗi WorkContinuation.

Hãy xem một ví dụ. Trong ví dụ này, 3 công việc khác nhau của Worker được định cấu hình để chạy (có thể thực hiện song song). Sau đó, kết quả của các Worker này được gộp lại và chuyển tiếp đến công việc của Worker để lưu vào bộ nhớ đệm. Cuối cùng, dữ liệu đầu ra của công việc đó được chuyển vào một Worker đã tải lên. Công cụ này sẽ tải kết quả lên máy chủ từ xa.

Kotlin

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue()

Java

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(Arrays.asList(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue();

Hợp nhất dữ liệu đầu vào

Khi bạn liên kết đối tượng OneTimeWorkRequest, dữ liệu đầu ra của yêu cầu công việc chính được truyền vào làm đầu vào cho công việc phụ. Vì vậy, trong ví dụ trên, dữ liệu đầu ra của plantName1, plantName2plantName3 sẽ được truyền làm dữ liệu đầu vào đến yêu cầu cache.

Để quản lý dữ liệu đầu vào từ nhiều yêu cầu công việc chính, WorkManager sử dụng InputMerger.

WorkManager cung cấp hai loại InputMerger khác nhau:

  • OverwritingInputMerger cố gắng thêm tất cả các khoá từ dữ liệu đầu vào đến dữ liệu đầu ra. Trong trường hợp xảy ra xung đột, phương pháp này sẽ ghi đè tất cả các khoá đã thiết lập trước đó.

  • ArrayCreatingInputMerger cố gắng hợp nhất dữ liệu đầu vào để tạo mảng khi cần.

Nếu có trường hợp sử dụng cụ thể hơn, bạn có thể tự viết bằng cách phân lớp con InputMerger.

OverwritingInputMerger

OverwritingInputMerger là phương thức hợp nhất mặc định. Nếu có xung đột khoá trong quá trình hợp nhất, giá trị mới nhất của khoá sẽ ghi đè bất kỳ phiên bản nào trước đó trong kết quả dữ liệu đầu ra.

Ví dụ: Nếu mỗi đầu vào của từng cây có một khoá khớp với tên biến thể tương ứng ("plantName1", "plantName2""plantName3"), dữ liệu truyền sang worker cache sẽ có ba cặp khoá-giá trị.

Sơ đồ thể hiện ba công việc truyền nhiều dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Vì tất cả ba kết quả đầu ra có các khoá khác nhau, nên công việc tiếp theo nhận được ba cặp giá trị-khoá.

Nếu có xung đột, worker hoàn thành sau cùng sẽ “wins” rồi giá trị của worker đó được truyền vào cache.

Sơ đồ thể hiện ba công việc truyền dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Trong trường hợp này, hai trong số các công việc đó tạo dữ liệu đầu ra bằng cùng một khoá. Vì vậy, công việc tiếp theo nhận được hai cặp khoá/giá trị, trong đó một dữ liệu đầu ra xung đột bị bỏ lại.

Vì yêu cầu công việc chạy song song nên không thể đảm bảo thứ tự thực hiện. Trong ví dụ trên, plantName1 có thể chứa giá trị của "tulip" hoặc "elm", tuỳ thuộc vào việc giá trị nào được ghi gần đây nhất. Nếu có nguy cơ xung đột khoá và bạn cần duy trì toàn bộ dữ liệu đầu ra khi gộp, thì ArrayCreatingInputMerger có thể là lựa chọn tốt hơn.

ArrayCreatingInputMerger

Trong ví dụ trên, giả sử nếu muốn duy trì dữ liệu đầu ra từ tất cả các Worker xử lý tên cây, chúng ta nên dùng ArrayCreatingInputMerger.

Kotlin

val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>()
   .setInputMerger(ArrayCreatingInputMerger::class)
   .setConstraints(constraints)
   .build()

Java

OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class)
       .setInputMerger(ArrayCreatingInputMerger.class)
       .setConstraints(constraints)
       .build();

ArrayCreatingInputMerger ghép nối từng khoá với một mảng. Nếu các khoá đều khác nhau, kết quả của bạn sẽ là các chuỗi mảng một phần tử.

Sơ đồ thể hiện ba công việc truyền nhiều dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Công việc tiếp theo nhận ba mảng, mỗi mảng cho một khoá đầu ra. Mỗi mảng có một thành phần.

Nếu có bất kỳ xung đột khoá nào, mọi giá trị tương ứng sẽ được nhóm vào cùng một mảng.

Sơ đồ thể hiện ba công việc truyền dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Trong trường hợp này, hai trong số các công việc đó tạo dữ liệu đầu ra bằng cùng một khoá. Công việc tiếp theo truyền hai mảng, mỗi mảng cho một khoá. Vì có hai kết quả đầu ra với khoá đó nên một trong những mảng này có hai thành phần.

Chuỗi tác vụ và các trạng thái công việc

Các chuỗi OneTimeWorkRequest thực thi tuần tự miễn là công việc hoàn thành (tức là các chuỗi này trả về Result.success()). Yêu cầu công việc có thể không thành công hoặc bị huỷ trong quá trình thực hiện, từ đó tác động đến các yêu cầu công việc phụ thuộc.

Khi OneTimeWorkRequest đầu tiên được xếp vào hàng đợi trong chuỗi yêu cầu công việc, toàn bộ yêu cầu công việc tiếp theo sẽ bị chặn lại cho đến khi công việc trong yêu cầu công việc đầu tiên đã hoàn tất.

Sơ đồ thể hiện chuỗi công việc. Công việc đầu tiên đã được thêm vào hàng đợi; tất cả công việc kế tiếp bị chặn lại cho đến khi công việc đầu tiên kết thúc.

Sau khi xếp vào hàng đợi và đáp ứng toàn bộ các quy tắc trong công việc, yêu cầu công việc đầu tiên bắt đầu tiến hành. Nếu công việc đã hoàn tất trong OneTimeWorkRequest gốc hoặc List<OneTimeWorkRequest> (tức kết quả trả về là Result.success()), nhóm yêu cầu công việc phụ thuộc tiếp theo sẽ được xếp vào hàng đợi.

Sơ đồ thể hiện chuỗi công việc. Khi công việc đầu tiên đã hoàn tất thành công, hai công việc kế tiếp sẽ được thêm ngay vào hàng đợi. Các công việc còn lại sẽ bị chặn cho đến khi các công việc trước đó hoàn tất.

Chỉ cần từng yêu cầu công việc đều hoàn tất thành công, mô hình này sẽ được áp dụng với phần còn lại của chuỗi yêu cầu công việc cho đến khi hoàn thành toàn bộ công việc trong chuỗi. Mặc dù là trường hợp đơn giản nhất và thường được ưu tiên, việc xử lý trạng thái lỗi cũng không kém phần quan trọng.

Nếu xảy ra lỗi trong lúc worker xử lý yêu cầu công việc, bạn có thể thử lại yêu cầu đó theo chính sách trì hoãn bạn xác định. Việc thử lại yêu cầu là một phần của chuỗi, tức là sẽ chỉ yêu cầu đó được thực hiện lại bằng dữ liệu đầu vào đã cấp. Mọi công việc chạy song song sẽ không bị ảnh hưởng.

Sơ đồ thể hiện chuỗi công việc. Một trong các công việc không thành công nhưng đã xác định được chính sách trì hoãn. Công việc đó sẽ được tiến hành lại sau một khoảng thời gian thích hợp. Các công việc tiếp theo trong chuỗi sẽ bị chặn lại cho đến khi công việc này hoàn tất.

Để biết thêm thông tin về cách xác định chiến lược thử lại tuỳ chỉnh, hãy xem phần Thử lại và chính sách trì hoãn.

Nếu không xác định được chính sách thử lại hay chính sách này đã hết hiệu lực hoặc bạn đã đạt được một số trạng thái mà OneTimeWorkRequest trả về Result.failure() thì yêu cầu công việc đó và toàn bộ các yêu cầu công việc phụ thuộc được đánh dấu thành FAILED.

Sơ đồ thể hiện chuỗi công việc. Một công việc không thực hiện thành công và không thể thử lại. Do đó, tất cả các công việc tiếp theo đều không thành công.

Hệ thống sẽ áp dụng cùng logic đó khi OneTimeWorkRequest bị huỷ. Hệ thống sẽ đánh dấu mọi yêu cầu công việc phụ thuộc là CANCELLED và công việc sẽ không được thực thi.

Sơ đồ thể hiện chuỗi công việc. Một công việc đã bị huỷ. Do đó, toàn bộ công việc tiếp theo trong chuỗi này sẽ bị huỷ.

Lưu ý rằng nếu bạn thêm các yêu cầu công việc mới vào một chuỗi đã có các yêu cầu thất bại hoặc đã huỷ yêu cầu công việc, thì yêu cầu công việc vừa thêm cũng sẽ bị đánh dấu tương ứng là FAILED hoặc CANCELLED. Nếu bạn muốn mở rộng phạm vi công việc của chuỗi hiện tại, hãy xem APPEND_OR_REPLACE trong ExistingWorkPolicy.

Khi tạo các chuỗi yêu cầu công việc, yêu cầu công việc phụ thuộc phải xác định chính sách thử lại để đảm bảo rằng luôn hoàn thành công việc đúng hạn. Yêu cầu công việc không thành công có thể dẫn đến chuỗi chưa hoàn chỉnh và/hoặc trạng thái không mong muốn.

Để biết thêm thông tin, hãy xem phần Huỷ và dừng công việc.