更新已加入队列的工作

通过 WorkManager 更新WorkRequest后, 已将其加入队列。对于频繁更改的大型应用,通常有必要这样做 或者需要即时更新其 worker。自 WorkManager 起 2.8.0 版,则 updateWork() API 就是实现此目的的方法。

借助 updateWork() 方法,您可以更改 WorkRequest,而无需手动 将一个新的实例加入队列。这大大简化了 过程。

避免取消工作

通常,您应该避免取消现有 WorkRequest,并将新的 WorkRequest 加入队列。 一个。否则可能会导致应用重复执行某些任务,并且您可能需要 编写大量额外代码。

请参考以下示例,了解取消 WorkRequest 可能会导致哪些情况 难度:

  • 后端请求:如果您在 Worker 计算期间将其取消 要发送到服务器的载荷,则新的 Worker 需要重新开始, 重新计算可能费用高昂的载荷。
  • 时间安排:如果您取消 PeriodicWorkRequest,并且想要 例如新的 PeriodicWorkRequest 按相同的时间表执行,您需要 计算时间偏移,以确保新的执行时间保持一致 上一个工作请求的状态。

借助 updateWork() API,您可以更新工作请求的约束条件和 而无需将新请求取消和加入队列。

何时取消工作

在某些情况下,您应该直接取消 WorkRequest,而不是 调用 updateWork()。如果您想更改 已加入队列的工作的基本性质。

何时更新单位地址

假设某个照片应用每天备份用户的照片。它具有 为此,将 PeriodicWorkRequest 加入队列。WorkRequest 存在约束条件 要求设备充电并连接到 Wi-Fi 网络。

但是,用户每天仅使用快速充电桩为其设备充电 20 分钟 充电器。在这种情况下,应用可能需要更新 WorkRequest 以放宽 这样即使设备未连接,它仍然可以上传照片。 没有充满电。

在这种情况下,您可以使用 updateWork() 方法来更新工作 请求的限制条件。

如何更新单位地址

updateWork() 方法提供了一种更新现有的现有服务 WorkRequest,而不必取消新请求并将其加入队列。

如需使用更新已加入队列的工作,请按以下步骤操作:

  1. 获取已加入队列的工作的现有 ID:获取 要更新的广告系列。您可以使用任意 getWorkInfo API,或手动保留初始 使用公共属性稍后检索的 WorkRequest WorkRequest.id,然后再将其加入队列。
  2. Create new WorkRequest:创建一个新的 WorkRequest 并使用 WorkRequest.Builder.setID(),以设置其 ID 以匹配现有 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()

作业更新政策

以前,更新定期工作的推荐解决方案是将一个 将 PeriodicWorkRequest 替换为政策 ExistingPeriodicWorkPolicy.REPLACE。 如果存在具有相同唯一 id 的待处理 PeriodicWorkRequest,则新的 系统会取消并删除相应工作请求此政策现已弃用 支持使用 ExistingPeriodicWorkPolicy.UPDATE 完成工作流。

例如,将 enqueueUniquePeriodicWorkPeriodicWorkRequest,您可以使用PeriodicWorkRequest ExistingPeriodicWorkPolicy.UPDATE 政策。如果存在待处理 PeriodicWorkRequest 时,WorkManager 会将其更新为 新规范按照此工作流程操作后,就不再需要使用 updateWork()