WorkManager ช่วยให้คุณสร้างและจัดคิวเชนของงานที่ระบุงานที่ขึ้นต่อกันหลายรายการและกำหนดลำดับที่ควรเรียกใช้งานได้ ฟังก์ชันนี้มีประโยชน์อย่างยิ่งเมื่อคุณต้องการเรียกใช้หลายงานตามลำดับที่เฉพาะเจาะจง
หากต้องการสร้างเชนของงาน คุณสามารถใช้ WorkManager.beginWith(OneTimeWorkRequest) หรือ WorkManager.beginWith(List<OneTimeWorkRequest>) ซึ่งแต่ละรายการจะแสดงผลอินสแตนซ์ของ WorkContinuation
จากนั้นคุณจะใช้ WorkContinuation เพื่อเพิ่มอินสแตนซ์ OneTimeWorkRequest ที่ขึ้นต่อกันได้โดยใช้
then(OneTimeWorkRequest)
หรือ
then(List<OneTimeWorkRequest>)
การเรียกใช้ WorkContinuation.then(...) ทุกครั้งจะแสดงผลอินสแตนซ์ใหม่ของ WorkContinuation หากคุณเพิ่ม List ของอินสแตนซ์ OneTimeWorkRequest รายการ คำขอเหล่านี้อาจทำงานพร้อมกันได้
สุดท้าย คุณสามารถใช้เมธอด WorkContinuation.enqueue() เพื่อenqueue()เชนของ WorkContinuation ได้
มาดูตัวอย่างกัน ในตัวอย่างนี้ มีการกำหนดค่าให้งานของผู้ปฏิบัติงาน 3 งานทำงาน (อาจทำงานพร้อมกัน) จากนั้นระบบจะรวมผลลัพธ์ของ Worker เหล่านี้และส่งต่อไปยังงาน Worker ที่แคชไว้ สุดท้าย ผลลัพธ์ของงานนั้นจะส่งไปยัง Worker การอัปโหลด ซึ่งจะอัปโหลดผลลัพธ์ไปยังเซิร์ฟเวอร์ระยะไกล
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();
การรวมอินพุต
เมื่อคุณเชื่อมโยงอินสแตนซ์ OneTimeWorkRequest รายการ ผลลัพธ์ของคำของานหลักจะส่งต่อไปเป็นอินพุตให้กับคำของานย่อย ดังนั้นในตัวอย่างข้างต้น เอาต์พุตของ plantName1, plantName2 และ plantName3 จะถูกส่งเป็นอินพุตไปยังคำขอ cache
WorkManager ใช้ InputMerger เพื่อจัดการอินพุตจากคำของานหลักหลายรายการ
WorkManager มี InputMerger 2 ประเภทที่แตกต่างกัน ได้แก่
OverwritingInputMergerพยายามเพิ่มคีย์ทั้งหมดจากอินพุตทั้งหมดไปยังเอาต์พุต ในกรณีที่เกิดความขัดแย้ง ระบบจะเขียนทับคีย์ที่ตั้งค่าไว้ก่อนหน้านี้ArrayCreatingInputMergerพยายามผสานอินพุต โดยสร้างอาร์เรย์เมื่อจำเป็น
หากมี Use Case ที่เฉพาะเจาะจงมากขึ้น คุณสามารถเขียนของคุณเองได้โดยใช้คลาสย่อย InputMerger
OverwritingInputMerger
OverwritingInputMerger เป็นวิธีการรวมเริ่มต้น หากมีคีย์ที่ขัดแย้งกันในการผสาน ค่าล่าสุดของคีย์จะเขียนทับเวอร์ชันก่อนหน้าในข้อมูลเอาต์พุตที่ได้
เช่น หากอินพุตของโรงงานแต่ละรายการมีคีย์ที่ตรงกับชื่อตัวแปรที่เกี่ยวข้อง ("plantName1", "plantName2" และ "plantName3") ข้อมูลที่ส่งไปยัง Worker cache จะมีคู่คีย์-ค่า 3 คู่
หากเกิดความขัดแย้ง ผู้ปฏิบัติงานคนสุดท้ายที่ดำเนินการเสร็จสมบูรณ์จะเป็น "ผู้ชนะ" และระบบจะส่งค่าของผู้ปฏิบัติงานรายนั้นไปยัง cache
เนื่องจากคำของานทำงานพร้อมกัน จึงไม่มีการรับประกันลำดับการทำงาน ในตัวอย่างข้างต้น plantName1 อาจมีค่าเป็น "tulip" หรือ "elm" ขึ้นอยู่กับว่าค่าใดเขียนไว้เป็นค่าสุดท้าย หากมีโอกาสเกิดความขัดแย้งของคีย์และคุณต้องการเก็บรักษาข้อมูลเอาต์พุตทั้งหมดในการผสาน ArrayCreatingInputMerger อาจเป็นตัวเลือกที่ดีกว่า
ArrayCreatingInputMerger
สำหรับตัวอย่างข้างต้น เนื่องจากเราต้องการเก็บเอาต์พุตจาก Worker ชื่อพืชทั้งหมด เราจึงควรใช้ 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 จับคู่คีย์แต่ละรายการกับอาร์เรย์ หากแต่ละคีย์ไม่ซ้ำกัน ผลลัพธ์ที่ได้จะเป็นชุดอาร์เรย์ที่มีองค์ประกอบเดียว
หากมีคีย์ที่ทับซ้อนกัน ระบบจะจัดกลุ่มค่าที่เกี่ยวข้องไว้ด้วยกันในอาร์เรย์
การเชื่อมโยงและสถานะการทำงาน
เชนของ OneTimeWorkRequest จะทำงานตามลำดับตราบใดที่งานเสร็จสมบูรณ์ (นั่นคือแสดงผล Result.success()) คำของานอาจล้มเหลวหรือถูกยกเลิกขณะทำงาน ซึ่งส่งผลกระทบต่อคำของานที่ขึ้นต่อกัน
เมื่อ OneTimeWorkRequest แรกอยู่ในคิวในเชนของคำของาน คำของานที่ตามมาทั้งหมดจะถูกบล็อกจนกว่างานของคำของานแรกจะเสร็จสมบูรณ์
เมื่อจัดคิวและเป็นไปตามข้อจำกัดของงานทั้งหมดแล้ว คำของานแรกจะเริ่มทำงาน หากงานเสร็จสมบูรณ์ในรูท OneTimeWorkRequest หรือ List<OneTimeWorkRequest> (นั่นคือแสดงผล Result.success()) ระบบจะจัดคิวคำของานที่ขึ้นต่อกันชุดถัดไป
ตราบใดที่คำของานแต่ละรายการเสร็จสมบูรณ์ รูปแบบเดียวกันนี้จะเผยแพร่ผ่านคำของานที่เหลือในเชนจนกว่างานทั้งหมดในเชนจะเสร็จสมบูรณ์ แม้ว่าจะเป็นกรณีที่ง่ายที่สุดและมักเป็นที่ต้องการ แต่สถานะข้อผิดพลาดก็มีความสำคัญไม่แพ้กัน
เมื่อเกิดข้อผิดพลาดขณะที่เวิร์กเกอร์กำลังประมวลผลคำของาน คุณสามารถลองส่งคำขอนั้นอีกครั้งตามนโยบาย Backoff ที่คุณกำหนด การลองส่งคำขอที่เป็นส่วนหนึ่งของเชนอีกครั้งหมายความว่าระบบจะลองส่งคำขอนั้นอีกครั้งด้วยข้อมูลอินพุตที่ระบุไว้ งานที่ทำงานพร้อมกันจะไม่ได้รับผลกระทบ
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดกลยุทธ์การลองใหม่ที่กำหนดเองได้ที่นโยบายการลองใหม่และการ Backoff
หากนโยบายการลองใหม่นั้นไม่ได้กำหนดไว้หรือหมดลง หรือคุณเข้าสู่สถานะที่ OneTimeWorkRequest แสดงผลเป็น Result.failure() ระบบจะทำเครื่องหมายคำของานนั้นและคำของานที่เกี่ยวข้องทั้งหมดเป็น FAILED.
ตรรกะเดียวกันนี้จะใช้เมื่อมีการยกเลิก OneTimeWorkRequest คำของานที่ขึ้นต่อกันจะได้รับการทำเครื่องหมายเป็นCANCELLEDด้วย และงานดังกล่าวจะไม่ได้รับการดำเนินการ
โปรดทราบว่าหากคุณเพิ่มคำของานลงในเชนที่มีคำของานที่ล้มเหลวหรือถูกยกเลิก คำของานที่เพิ่มใหม่จะได้รับการทำเครื่องหมายเป็นFAILEDหรือCANCELLEDตามลำดับด้วย หากต้องการขยายงานของเชนที่มีอยู่ โปรดดู APPEND_OR_REPLACE ใน ExistingWorkPolicy
เมื่อสร้างเชนของคำของาน คำของานที่ขึ้นต่อกันควรกำหนดนโยบายการลองใหม่เพื่อให้แน่ใจว่างานจะเสร็จสมบูรณ์อย่างทันท่วงทีเสมอ คำของานที่ล้มเหลวอาจส่งผลให้เชนไม่สมบูรณ์และ/หรือสถานะที่ไม่คาดคิด
ดูข้อมูลเพิ่มเติมได้ที่การยกเลิกและการหยุดงาน