本篇记录下WorkManager
的进度观察和多个Work
链接的内容。
WorkManager
提供对进度的观察,示例如下:
更新进度:
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.WorkerParameters
import kotlinx.coroutines.delay
class ProgressWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
companion object {
const val Progress = "Progress"
private const val delayDuration = 1L
}
override suspend fun doWork(): Result {
val firstUpdate = workDataOf(Progress to 0)
val lastUpdate = workDataOf(Progress to 100)
setProgress(firstUpdate)
delay(delayDuration)
setProgress(lastUpdate)
return Result.success()
}
}
观察进度:
WorkManager.getInstance(applicationContext)
// requestId is the WorkRequest id
.getWorkInfoByIdLiveData(requestId)
.observe(observer, Observer { workInfo: WorkInfo? ->
if (workInfo != null) {
val progress = workInfo.progress
val value = progress.getInt(Progress, 0)
// Do something with progress information
}
})
需要注意的是,getWorkInfoById()
在实际测试中无法监听进度,暂时原因未知。而且仅会在任务开始时候执行一次,其后就不再执行,所以倘若任务延迟后,那么可能获取不到实际的结果。
WorkManager
在实际工作中允许将多个Work
进行链接,进行并发或者顺序执行。
如需创建工作链,您可以使用
WorkManager.beginWith(OneTimeWorkRequest)
或WorkManager.beginWith(List<OneTimeWorkRequest>)
,这会返回WorkContinuation
实例。然后,可以使用
WorkContinuation
通过then(OneTimeWorkRequest)
或then(List<OneTimeWorkRequest>)
添加OneTimeWorkRequest
依赖实例。 .每次调用
WorkContinuation.then(...)
都会返回一个新的WorkContinuation
实例。如果添加了OneTimeWorkRequest
实例的List
,这些请求可能会并行运行。最后,您可以使用
WorkContinuation.enqueue()
方法对WorkContinuation
工作链执行enqueue()
操作。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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
在WorkManager
的链式调用中,每一次的工作结果都会成为下一个工作的输入内容。为了管理这种事情,WorkManager
使用 InputMerger
来处理这种事情。
WorkManager 提供两种不同类型的
InputMerger
:
OverwritingInputMerger
会尝试将所有输入中的所有键添加到输出中。如果发生冲突,它会覆盖先前设置的键。
ArrayCreatingInputMerger
会尝试合并输入,并在必要时创建数组。如果您有更具体的用例,则可以创建
InputMerger
的子类来编写自己的用例
示例代码如下:
val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>()
.setInputMerger(ArrayCreatingInputMerger::class)
.setConstraints(constraints)
.build()