通过 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
,而不必取消新请求并将其加入队列。
如需使用更新已加入队列的工作,请按以下步骤操作:
- 获取已加入队列的工作的现有 ID:获取
要更新的广告系列。您可以使用任意
getWorkInfo
API,或手动保留初始 使用公共属性稍后检索的 WorkRequestWorkRequest.id
,然后再将其加入队列。 - Create new WorkRequest:创建一个新的
WorkRequest
并使用WorkRequest.Builder.setID()
,以设置其 ID 以匹配现有 IDWorkRequest
。 - 设置约束条件:使用
WorkRequest.Builder.setConstraints()
将 WorkManager 中新增了约束条件。 - 调用 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
的生成,请按以下步骤操作:
- WorkInfo:调用
WorkManager.getWorkInfoById()
以检索实例 (共WorkInfo
),与您的WorkRequest
相对应。- 您可以调用返回
WorkInfo
的多种方法之一。有关 相关信息,请参阅 WorkManager 参考文档。
- 您可以调用返回
- 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
完成工作流。
例如,将 enqueueUniquePeriodicWork
与
PeriodicWorkRequest
,您可以使用PeriodicWorkRequest
ExistingPeriodicWorkPolicy.UPDATE
政策。如果存在待处理
PeriodicWorkRequest
时,WorkManager 会将其更新为
新规范按照此工作流程操作后,就不再需要使用
updateWork()
。