更新已排入佇列的工作

透過 WorkManager,您可以在取得WorkRequest 則新增至佇列。若是經常變更的大型應用程式,通常需要這麼做 或是需要即時更新員工截至 WorkManager 2.8.0 版時,使用 updateWork() API 即可。

updateWork() 方法可讓您變更 WorkRequest 會即時,而不需要手動完成整個程序 取消並將新的佇列排入佇列這可大幅簡化 上傳資料集之後,您可以運用 AutoML 自動完成部分資料準備工作

避免取消工作

通常您應該避免取消現有的 WorkRequest,並將新的工作排入佇列 第一項。這種做法可能導致應用程式重複執行特定工作,而且可能會要求你 大量編寫額外程式碼

以下舉例說明取消 WorkRequest 的可能原因 問題:

  • 後端要求:在運算期間取消 Worker 要傳送至伺服器的酬載,則必須重新開始新的 Worker, 系統可能會重新運算可能昂貴的酬載
  • 排程:如果取消PeriodicWorkRequest,且已完成 例如新的 PeriodicWorkRequest 是在同一時間執行 來計算時間偏移,確保新的執行時間一致 與先前的工作要求搭配使用

updateWork() API 可讓您更新工作要求的限制,並 以便輕鬆取消及將新要求排入佇列。

何時取消工作

在某些情況下,建議您直接取消 WorkRequest,而不是 呼叫 updateWork()。如果您想變更 執行方式

更新工作的時機

假設有一個相片應用程式會每日備份使用者的相片,它有 將 PeriodicWorkRequest 加入佇列即可。WorkRequest 設有限制 裝置必須處於充電狀態並連上 Wi-Fi。

不過,使用者只要使用 。在此情況下,應用程式可能會想更新 WorkRequest 來放寬 ,這樣即使裝置裝置,仍然可以上傳相片 沒有充飽電

在這種情況下,您可以使用 updateWork() 方法更新工作 限制

如何更新公司地址

updateWork() 方法可讓您輕鬆更新現有 WorkRequest,不必取消操作並排入佇列。

如要使用更新排入佇列的工作,請按照下列步驟操作:

  1. 取得已排入佇列工作的現有 ID:取得 WorkRequest 的 ID 進行更新。您可以透過 getWorkInfo API,或是手動保存初始版本的 ID 使用公用屬性擷取 WorkRequest 以供稍後擷取 WorkRequest.id,然後再將佇列加入佇列。
  2. 建立新的 WorkRequest:建立新的 WorkRequest,並使用 WorkRequest.Builder.setID() 將其 ID 設為與現有 WorkRequest
  3. 設定限制條件:使用 WorkRequest.Builder.setConstraints() 來傳遞 WorkManager 的新限制。
  4. 呼叫 updateWork:將新的 WorkRequest 傳遞至 updateWork()

更新工作範例

以下是 Kotlin 的程式碼片段範例,示範如何將 updateWork() 方法可變更所用 WorkRequest 的電池限制 上傳相片:

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)
}

處理結果

updateWork() 會傳回 ListenableFuture<UpdateResult>。提供的 UpdateResult 可包含其中一個值,用以表示是否包含其中一個值 WorkManager 能夠套用變更。也會指出 以套用變更

詳情請參閱 updateWork() UpdateResult 參考資料

追蹤世代的作業

每次更新 WorkRequest 時,其 generation 都會遞增 1。這個 可讓您追蹤目前排入佇列的 WorkRequest。 產生版本後,您就能進一步掌控觀察、追蹤及測試工作 要求。

如要產生 WorkRequest,請按照下列步驟操作:

  1. WorkInfo:呼叫 WorkManager.getWorkInfoById() 以擷取執行個體 (WorkInfo) 對應您的 WorkRequest
  2. getGeneration:呼叫 getGeneration() 實例 WorkInfo。傳回的 Int 對應 WorkRequest
    • 請注意,系統不會提供產生欄位或屬性,只有 WorkInfo.getGeneration() 方法。

追蹤產生範例

以下是上述工作流程的實作範例: 擷取 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()

工作更新政策

先前,建議更新定期工作的建議做法是將 政策為 ExistingPeriodicWorkPolicy.REPLACEPeriodicWorkRequest。 如果有包含相同不重複 id 的待處理 PeriodicWorkRequest,則新的 工作要求就會取消並刪除這項政策現已淘汰, 而改用 ExistingPeriodicWorkPolicy.UPDATE 處理工作流程

例如,使用 enqueueUniquePeriodicWork 搭配 PeriodicWorkRequest 時,您可以使用PeriodicWorkRequest ExistingPeriodicWorkPolicy.UPDATE政策。如果有 如果 PeriodicWorkRequest 使用相同的不重複名稱,WorkManager 就會將其更新為 新規格導入此工作流程後,不必使用 updateWork()