的名字APPEND_OR_REPLACE
具有误导性,阅读本文后您会认为这是Worker
如果发生故障,将替换以前的工作人员,或者如果正在运行,则追加,这是错误的!
APPEND_OR_REPLACE
意味着将此工作人员附加到正在运行的chain或者如果前一个链失败,则用新链替换该链(创建一个新链并重新开始,这就像硬重置)
伪代码
if (getChainWithUniqueTag(TAG).status == CANCELLED || FAILED) {
createNewChine()
}
addRequestToChainWithTag(TAG,request)
现在应该更有意义了,它是关于当前的状态chain而不是Work
为了进一步确认这一点,尝试用唯一的名称启动一个worker1,然后让它失败(通过调用Result.failure
)然后创建另一个worker2APPEND
具有相同的唯一名称,worker2
会在开始之前直接失败,因为它属于失败链。
如果您尝试相同的场景但使用APPEND_OR_REPLACE
, worker2
将启动一个新的链条并继续正常工作。
考虑这个例子:
val request1 = OneTimeWorkRequestBuilder<SleepWorker>()
.setInputData(workDataOf(KEY_BREAK_AT to 5))
.build()
val request2 = OneTimeWorkRequestBuilder<SleepWorker>()
.build()
workManager.enqueueUniqueWork(
TAG,
ExistingWorkPolicy.APPEND_OR_REPLACE,
request1
)
// Infinite loop
while (workManager.getWorkInfoById(request1.id).get().state == WorkInfo.State.RUNNING){}
workManager.enqueueUniqueWork(
TAG,
ExistingWorkPolicy.APPEND_OR_REPLACE,
request2
)
SleepWorker
class SleepWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result {
val breakAt = inputData.getInt(KEY_BREAK_AT,-1)
repeat(10) {
if(it == breakAt) return Result.failure()
println("$it")
delay(1000L)
}
return Result.success()
}
}
现在在这种情况下,request1
会失败,然后我们开始request2
并且它会正常启动,因为FLAG是APPEND_OR_REPLACE
,
如果标志是APPEND
then request2
将失败。
PS:尝试移动第二个enqueueUniqueWork
for request2
在无限之前while
loop, request2
也会失败。有道理吗?
因为当我们打电话时enqueueUniqueWork
当时该链条很好,因此该作业已成功添加到该链条中。