定義您的
Worker
和
你的 WorkRequest
最後一步是將工作加入佇列將工作排入佇列的最簡單方式
那就是呼叫 WorkManager enqueue()
方法,並傳遞 WorkRequest
決定要執行的版本
Kotlin
val myWork: WorkRequest = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork)
Java
WorkRequest myWork = // ... OneTime or PeriodicWork WorkManager.getInstance(requireContext()).enqueue(myWork);
因此,建議您在將工作排入佇列時謹慎小心,以免重複。 舉例來說,應用程式可能會嘗試 每 24 小時將記錄檔記錄傳送至後端服務有事時您就會 最終會將相同的工作多次排入佇列 執行一次 如要達到這個目標,您可以將工作安排為「不重複工作」。
不重複工作
「不重複工作」這個強大概念 可確保您只有一個物件 指定一次特定名稱的工作執行個體。唯一名稱與 ID 不同 為人類可讀且由開發人員指定,而不是自動產生 由 WorkManager 處理取消喜歡 tags,不重複 只會與單一工作例項建立關聯。
不重複工作可套用至一次性和週期性工作。您可以建立 不同的工作序列來呼叫不同的方法,實際情況取決於 安排週期性或一次性工作
- 適用於一次性工作的
WorkManager.enqueueUniqueWork()
- 適用於週期性工作的
WorkManager.enqueueUniquePeriodicWork()
這兩種方法都接受 3 個引數:
- uniqueWorkName - 用來識別作品的
String
請求。 - existingWorkPolicy - 向 WorkManager 指示要執行的動作的
enum
如果有同一名稱已有未完成的工作鏈結詳情請見 衝突解決政策。 - work - 要安排的
WorkRequest
。
只要使用不重複的工作,我們就能修正先前所述的重複排程問題。
Kotlin
val sendLogsWorkRequest = PeriodicWorkRequestBuilderS<endLogsWorker(>24, TimeUnit.HOURS) .setConstraints(Constraints.Builder() .setRequiresCharging(true) .build() ) .build() WorkManager.getInstance(this).enqueueUniquePeriodicWork( "sendLogs", ExistingPeriodicWorkPolicy.KEEP, sendLogsWorkRequest )
Java
PeriodicWorkRequest sendLogsWorkRequest = new PeriodicWorkRequest.Builder(SendLogsWorker.class, 24, TimeUnit.HOURS) .setConstraints(new Constraints.Builder() .setRequiresCharging(true) .build() ) .build(); WorkManager.getInstance(this).enqueueUniquePeriodicWork( "sendLogs", ExistingPeriodicWorkPolicy.KEEP, sendLogsWorkRequest);
現在,如果 sendLogs 工作已在佇列中,而程式碼同時執行, 工作,而且不會新增任何工作。
如果您需要逐步建構 長時間執行任務例如,相片編輯應用程式可能會讓使用者復原 需要長時間的動作每項復原作業可能需要一些時間才能完成,但 這些動作必須以正確順序執行在這個範例中,應用程式 建立「復原」鏈結並視需要將每項復原作業附加至鏈結。 請參閱將工作鏈結在一起一文 ,掌握更多詳細資訊。
衝突解決政策
安排不重複工作時,您必須告知 WorkManager 在何時採取行動 發生衝突。如要這麼做,請在將工作加入佇列時傳遞列舉值。
如果是一次性工作,您需要提供
ExistingWorkPolicy
,
支援 4 個處理衝突的選項。
REPLACE
部 重新投入工作這個選項會取消現有工作。KEEP
個既有工作和 即可忽略新工作APPEND
要將新工作設為 停用現有工作這項政策會使新作業生效 鏈結至 現有工作,在現有工作結束後執行。
現有工作會成為新工作的「先決條件」。如果現有作業
變成 CANCELLED
或 FAILED
,而新工作也會變為 CANCELLED
或 FAILED
。
如果您希望新工作不受現有工作狀態影響
請改用 APPEND_OR_REPLACE
。
APPEND_OR_REPLACE
敬上 函式與APPEND
類似,差別在於前者不受 事前準備工作狀態。如果現有作品為CANCELLED
或FAILED
,新工作仍會執行。
如果是週期性工作,您必須提供
ExistingPeriodicWorkPolicy
、
支援 2 個選項:REPLACE
和 KEEP
。這些選項的作用
做為 ExistingWorkPolicy 的對應項目
觀察你的工作
將工作加入佇列後,您可以隨時透過查詢
WorkManager 依據其 name
、id
或相關 tag
。
Kotlin
// by id workManager.getWorkInfoById(syncWorker.id) // ListenableFutureW<orkInfo<>/span> // by name workManager.getWorkInfosForUniqueWork("sync") // ListenableFutureL<istW<orkInfo<>/span> > // by tag workManager.getWorkInfosByTag("syncTag") // ListenableFutureL<istW<orkInfo<>/span> >
Java
// by id workManager.getWorkInfoById(syncWorker.id); // ListenableFutureW<orkInfo<>/span> // by name workManager.getWorkInfosForUniqueWork("sync"); // ListenableFutureL<istW<orkInfo<>/span> > // by tag workManager.getWorkInfosByTag("syncTag"); // ListenableFutureL<istW<orkInfo<>/span> >
查詢會傳回
ListenableFuture
敬上
WorkInfo
物件的所有值,其中含有
id
工作、其標記、其
目前 State
,以及任何輸出資料
設定方式
Result.success(outputData)
。
各個 Service 適用的 LiveData
變化版本
方法可讓您註冊 WorkInfo
事件監聽器。比方說,在活動期間
部分工作已成功完成,您可以依下列方式進行設定:
Kotlin
workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(viewLifecycleOwner) { workInfo - > if(workInfo?.state == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show() } }
Java
workManager.getWorkInfoByIdLiveData(syncWorker.id) .observe(getViewLifecycleOwner(), workInfo - >{ if (workInfo.getState() != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) { Snackbar.make(requireView(), R.string.work_completed, Snackbar.LENGTH_SHORT) .show(); } });
複雜的工作查詢
WorkManager 2.4.0 以上版本支援使用
WorkQuery
物件。WorkQuery 支援
使用標記、狀態和不重複工作名稱的組合來查詢工作。
以下範例顯示如何找出所有與代碼「syncTag」一起執行的作業。
處於 FAILED
或 CANCELLED
狀態,且專屬的工作名稱
「preProcess」或「sync」。
Kotlin
val workQuery = WorkQuery.Builder .fromTags(listOf("syncTag")) .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(listOf("preProcess", "sync") ) .build() val workInfos: ListenableFutureL<istW<orkInfo >>= workManager.getWorkInfos(workQuery)
Java
WorkQuery workQuery = WorkQuery.Builder .fromTags(Arrays.asList("syncTag")) .addStates(Arrays.asList(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED)) .addUniqueWorkNames(Arrays.asList("preProcess", "sync") ) .build(); ListenableFutureL<istW<orkInfo >>workInfos = workManager.getWorkInfos(workQuery);
WorkQuery
中的每個元件 (標記、狀態或名稱) 都具有 AND
關係。而元件中的每個值都具有 OR
邏輯關係。例如:(name1 OR name2
OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...)
。
WorkQuery
也適用於 LiveData 對等項目 getWorkInfosLiveData()
。
取消及停止工作
如果不再需要執行已排入佇列的工作,
取消。工作可以透過 name
、id
或 tag
取消
相關聯的資源
Kotlin
// by id workManager.cancelWorkById(syncWorker.id) // by name workManager.cancelUniqueWork("sync") // by tag workManager.cancelAllWorkByTag("syncTag")
Java
// by id workManager.cancelWorkById(syncWorker.id); // by name workManager.cancelUniqueWork("sync"); // by tag workManager.cancelAllWorkByTag("syncTag");
實際上,WorkManager 會檢查
作品的 State
。如果工作內容是
已完成
基本上不會有任何影響否則,工作狀態會變更為
CANCELLED
和工作
因此無法再執行不限
WorkRequest
職缺取決於
這個領域
且為 CANCELLED
。
目前使用 RUNNING
網域
接到來電
ListenableWorker.onStopped()
。
覆寫這個方法即可處理任何潛在的清理作業。查看停止
執行中的 worker。
停止執行中的工作站
以下幾個不同的原因可能會導致 WorkManager 停止執行 Worker
:
- 您已明確要求取消 (透過致電)
例如
WorkManager.cancelWorkById(UUID)
)。 - 就「不重複工作」來說
您明確將新的
WorkRequest
加入佇列,其中包含ExistingWorkPolicy
/REPLACE
。 系統會立即將舊的WorkRequest
視為取消, - 也不會再滿足您的工作限制條件。
- 系統因故指示應用程式停止工作。這可以 就會發生這種情形。工作: 排定於稍後重試
在下列情況下,工作站將會停止運作。
您應配合取消所有進行中的工作,並釋出任何 資源數量舉例來說, 處理資料庫和檔案的方式有兩種機制 處理工作工作站何時停止運作
onStopped() 回呼
WorkManager 叫用
ListenableWorker.onStopped()
敬上
工作站停止執行。覆寫這個方法即可關閉
您可操作的任何資源
isStopped() 屬性
您可以呼叫
ListenableWorker.isStopped()
方法,檢查工作站是否已停止。如果您是
在工作站中執行長時間或重複作業時
請經常檢查這項資源,並視為盡快停止工作的信號
。
注意:WorkManager 會忽略
工作站設定的 Result
接收到 onStop 信號,因為已將 worker 視為
已停止。