Android CoroutineWorker链式任务如何将失败子worker数据传递给末尾worker
结论先行
你无法仅通过监听链式任务末尾的WorkerZ拿到上游失败节点的输出数据。
原因
WorkManager的链式任务默认执行规则为:顺序执行的任务链中,任意一个Worker返回Result.failure(),整个任务链会立即终止,后续所有Worker(包括末尾的WorkerZ)都不会被调度执行。此时你监听到的WorkerZ的状态只会是CANCELLED,不会携带任何上游失败Worker的OutputData。
不需要全量监听所有Worker的两种实现方案
方案1:自定义状态透传(适合不需要终止任务链、或希望所有失败信息统一从末尾节点获取的场景)
你可以修改所有Worker的返回逻辑:执行失败时不返回Result.failure(),而是返回Result.success(),同时在OutputData中新增自定义字段标识执行结果、错误码、错误信息等内容。
后续所有Worker执行前先读取前序Worker传递的输入数据,如果识别到上游已经返回失败,就直接透传错误数据不需要执行自身逻辑,一直透传到末尾的WorkerZ,此时你只需要监听WorkerZ的输出就能拿到全链路的成功/失败信息。
示例代码如下:
// WorkerC执行失败时的返回逻辑 val errorOutput = workDataOf( "is_chain_success" to false, "error_worker_name" to "WorkerC", "error_code" to 1003, "error_msg" to "本地文件读取失败" ) return Result.success(errorOutput) // 后续WorkerD、WorkerZ的前置判断逻辑 override fun doWork(): Result { val preOutput = inputData if(!preOutput.getBoolean("is_chain_success", true)) { // 上游已失败,直接透传数据 return Result.success(preOutput) } // 正常执行自身逻辑 // ... }
方案2:Tag统一监听(适合需要中间失败就终止任务链的场景)
提交任务链时给所有Worker添加同一个自定义Tag,你只需要监听这个Tag对应的所有WorkInfo变化即可,不需要单独给每个Worker设置监听。
当任务链中途失败时,遍历返回的WorkInfo列表,找到状态为FAILED的节点,就能直接读取它的OutputData。
示例代码如下:
// 提交任务时给所有Worker添加同一个Tag val workerA = OneTimeWorkRequestBuilder<WorkerA>() .addTag("custom_chain_tag") .build() // WorkerB、WorkerC、WorkerD、WorkerZ都添加同一个Tag // 构建链式任务提交 WorkManager.getInstance(context) .beginWith(workerA) .then(workerB) .then(workerC) .then(workerD) .then(workerZ) .enqueue() // 统一监听Tag的任务状态 WorkManager.getInstance(context) .getWorkInfosByTagLiveData("custom_chain_tag") .observe(this) { workInfoList -> // 匹配失败的Worker workInfoList.firstOrNull { it.state == WorkInfo.State.FAILED }?.let { failedInfo -> val errorData = failedInfo.outputData // 处理失败逻辑 } // 匹配末尾成功的Worker,判断全链路成功 workInfoList.firstOrNull { it.state == WorkInfo.State.SUCCEEDED && it.tags.contains(WorkerZ::class.java.canonicalName) }?.let { // 处理全链路成功逻辑 } }
内容的提问来源于stack exchange,提问作者Hector
相关产品推荐
相关产品推荐

