WorkManager 可讓您建立工作鏈結並排入佇列;這個工作鏈結可指定多個相依工作並定義其執行順序。如果您需要依特定順序執行多項工作,這項功能非常實用。
如要建立工作鏈結,您可以使用 WorkManager.beginWith(OneTimeWorkRequest)
或 WorkManager.beginWith(List<OneTimeWorkRequest>)
,每個事件都會傳回 WorkContinuation
的執行個體。
接著,WorkContinuation
可用來新增採用 then(OneTimeWorkRequest)
或 then(List<OneTimeWorkRequest>)
的相依 OneTimeWorkRequest
執行個體。
每次叫用 WorkContinuation.then(...)
都會傳回 WorkContinuation
的「新」執行個體。如果新增 OneTimeWorkRequest
執行個體的 List
,這些要求可能會同時執行。
最後,您可以使用 WorkContinuation.enqueue()
方法來 enqueue()
您的 WorkContinuation
鏈結。
讓我們來看看下面這個例子。在這個範例中,3 個不同的工作站工作都設定為執行 (可能同時)。然後,系統會彙整這些工作站的結果,並傳遞至快取工作站工作。最後,該工作的輸出內容會傳遞至上傳工作站,以便將結果上傳至遠端伺服器。
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
:
OverwritingInputMerger
會嘗試將所有輸入內容中的鍵新增至輸出內容。如果發生衝突,就會覆寫先前設定的鍵。ArrayCreatingInputMerger
會嘗試合併輸入內容,並視需要建立陣列。
如果您有更具體的用途,可以將 InputMerger
設為子類別,自行編寫用途。
OverwritingInputMerger
OverwritingInputMerger
是預設的合併方法。如果合併方法中發生鍵衝突,鍵的最新值將會覆寫所產生的輸出內容資料中的先前版本。
舉例來說,如果每個植物輸入內容的鍵符合各自的變數名稱 ("plantName1"
、"plantName2"
和 "plantName3"
),則傳遞至 cache
工作站的資料會具備三個鍵/值組合。
如有衝突,則最後一個完成的工作站「勝出」,而其值會傳遞至 cache
。
由於工作要求是同時執行,因此無法保證其執行順序。在上述範例中,視最後寫入的值而定,plantName1
可保留 "tulip"
或 "elm"
的值。如果您可能遇到鍵衝突,而且需要在合併方法中保留所有輸出內容資料,選擇 ArrayCreatingInputMerger
可能更適合。
ArrayCreatingInputMerger
針對上述範例,假設我們要保留所有植物名稱工作站的輸出內容,則應使用 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()
),系統就會將下一組相依工作要求排入佇列。
只要每個工作要求都順利完成,相同的模式就會在其他工作要求鏈結如法炮製,直到鏈結中的所有工作都完成為止。雖然這是最簡單且經常偏好使用的情況,但錯誤狀態同樣必須處理。
如果工作站在處理工作要求時發生錯誤,可以按照您定義的輪詢政策重試該要求。重試鏈結內的要求時,系統只會以要求中提供的輸入內容資料重試要求。但所有同時執行的作業都不會受到影響。
如要進一步瞭解如何定義自訂重試策略,請參閱重試和輪詢政策。
如果該重試政策未定義或用盡,或者到達 OneTimeWorkRequest
傳回 Result.failure()
的特定狀態,系統就會將該工作要求和所有相依工作要求標示為 FAILED.
OneTimeWorkRequest
遭到取消時也適用同樣的邏輯。所有相依工作要求都會標示為 CANCELLED
,系統不會執行其工作。
請注意,如果您要在鏈結已失敗或已取消工作要求時附加更多工作要求,那麼新附加的工作要求也會分別標示為 FAILED
或 CANCELLED
。如要擴充現有鏈結的工作,請參閱 ExistingWorkPolicy 中的 APPEND_OR_REPLACE
一節。
建立工作要求鏈結時,相依工作要求應定義重試政策,以確保工作一定會及時完成。失敗的工作要求可能會導致鏈結不完整和/或非預期的狀態。
詳情請參閱取消及停止工作。