WorkManager进度事件未传递:监听Worker完成状态始终失败
问题描述
我尝试监听Worker的工作完成状态,Worker代码如下:
override suspend fun doWork(): Result = withContext(Dispatchers.IO) { val collectionName = checkNotNull(inputData.getString(COLLECTION_NAME_KEY)) val uris = checkNotNull(inputData.getStringArray(URIS_KEY)?.toList()?.map { Uri.parse(it) }) setForegroundAsync(createForegroundInfo()) val collectionId = Random(System.currentTimeMillis()).nextLong() val comics = saveFileAndCreateComics(collectionId, uris) val collection = ComicCollection(id = collectionId, name = collectionName) database.comicCollectionDao().insert(collection, comics) setProgress(workDataOf(IMPORT_FINISHED to true)) // 传递完成事件 Result.success() }
监听代码:
val workManager = WorkManager.getInstance(context) val data = Data.Builder() .putString(ImportFilesWorker.COLLECTION_NAME_KEY, collectionName) .putStringArray(ImportFilesWorker.URIS_KEY, uris.map { it.toString() }.toTypedArray()) .build() val uploadWorkRequest = OneTimeWorkRequestBuilder<ImportFilesWorker>() .setInputData(data) .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .build() workManager.enqueueUniqueWork(WORK_NAME, ExistingWorkPolicy.KEEP, uploadWorkRequest) WorkManager.getInstance(context) .getWorkInfoByIdLiveData(uploadWorkRequest.id) .observeForever { workInfo -> workInfo?.progress?.let { val finished = it.getBoolean(IMPORT_FINISHED, false) // 监听完成事件 Timber.e("FINISHED = $finished") } }
但日志始终显示FINISHED = false。我遗漏了什么?
更新:同时记录WorkInfo状态后,日志输出如下:
STATE = ENQUEUED FINISHED = false STATE = RUNNING FINISHED = false STATE = SUCCEEDED FINISHED = false
解决方法
1. 优先通过WorkInfo状态判断任务完成
WorkManager本身就通过WorkInfo.State标识任务状态,当状态变为SUCCEEDED时,就说明任务已完成,这是最可靠的判断方式,无需依赖progress传递标志。修改监听代码如下:
WorkManager.getInstance(context) .getWorkInfoByIdLiveData(uploadWorkRequest.id) .observeForever { workInfo -> workInfo?.let { when (it.state) { WorkInfo.State.SUCCEEDED -> { Timber.e("任务已完成") // 在这里处理任务完成后的逻辑 } WorkInfo.State.RUNNING -> { val finished = it.progress.getBoolean(ImportFilesWorker.IMPORT_FINISHED, false) Timber.e("FINISHED = $finished") } else -> Timber.e("当前任务状态:${it.state}") } } }
2. 检查常量定义一致性
确认IMPORT_FINISHED常量在Worker和监听代码中的字符串值完全一致,避免拼写错误导致无法读取正确的progress值。比如在Worker中定义:
const val IMPORT_FINISHED = "import_finished"
监听代码中必须直接引用这个常量,而非重新定义同名但值不同的常量:
val finished = it.progress.getBoolean(ImportFilesWorker.IMPORT_FINISHED, false)
3. 确保setProgress执行完成后再返回Result
虽然setProgress是挂起函数会等待执行完成,但如果任务执行速度极快,可能存在WorkManager还未同步progress状态,Worker就已结束的情况。可以尝试在setProgress后添加短暂延迟(仅用于排查,不推荐作为常规方案):
setProgress(workDataOf(IMPORT_FINISHED to true)) delay(100) // 短暂延迟确保状态同步 Result.success()
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

