如何确保WorkManager的setProgressAsync进度事件不丢失?
解决WorkManager进度更新事件丢失的方案
针对你遇到的进度事件丢失问题,核心原因是setProgressAsync的异步特性可能导致进度更新操作在任务结束后才执行,此时任务已脱离RUNNING状态,进度无法被观测。以下是几种可行的解决办法:
改用同步进度更新方法(推荐CoroutineWorker场景)
如果你使用的是CoroutineWorker,直接用挂起函数setProgress替代setProgressAsync。这个方法会等待进度更新操作完成后再继续执行后续任务,确保每一步进度都在任务RUNNING状态时被处理:class ProgressWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { repeat(10) { step -> val progress = workDataOf("CURRENT_STEP" to step + 1, "TOTAL_STEPS" to 10) setProgress(progress) // 同步更新,等待操作完成 delay(300) // 模拟任务耗时 } return Result.success() } }等待异步进度更新完成再结束任务(Worker场景)
若使用的是传统Worker,需确保每次调用setProgressAsync后,等待其返回的ListenableFuture完成再继续执行后续逻辑,避免任务提前结束:public class ProgressWorker extends Worker { public ProgressWorker(@NonNull Context context, @NonNull WorkerParameters params) { super(context, params); } @NonNull @Override public Result doWork() { for (int i = 0; i < 10; i++) { Data progress = new Data.Builder() .putInt("PROGRESS", (i + 1) * 10) .build(); try { // 阻塞等待进度更新完成 setProgressAsync(progress).get(); Thread.sleep(300); } catch (ExecutionException | InterruptedException e) { return Result.failure(); } } return Result.success(); } }避免过于频繁的进度更新
短时间内多次触发进度更新,WorkManager可能会合并部分事件。可以调整更新频率,比如每完成10%的任务再更新一次,或者在连续更新之间留出足够的处理时间,减少事件被合并的概率。确保观察者生命周期正确
观察WorkInfo的LiveData时,要保证观察者在任务RUNNING期间处于活跃状态。比如在Activity的onStart方法中开始观察,onStop方法中移除观察者,或者使用observeForever(注意要在合适时机移除,避免内存泄漏),确保不会因为页面销毁或生命周期切换错过进度事件。
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

