WorkManager的onStopped()方法未被回调该如何解决?
WorkManager onStopped方法未触发问题解决方案
常见触发失败原因
- Worker基类使用错误:只有继承自
CoroutineWorker或ListenableWorker的子类才会正常回调onStopped,如果使用默认的Worker基类,其同步执行的调度逻辑会在任务结束后直接销毁实例,不会触发该回调。 - 取消时机不对:只有任务处于运行中状态时被取消才会触发
onStopped,如果doWork已经执行完成返回了Result.success()/Result.failure()/Result.retry(),再调用取消接口不会触发回调。 - 进程被强杀场景:如果是用户在最近任务列表划掉应用、或者系统低内存杀进程,整个进程会被直接终止,不会给WorkManager预留回调
onStopped的时间,该场景下此方法本身就无法触发。
对应修复方案
- 替换Worker基类
Kotlin项目优先替换为
CoroutineWorker,示例如下:
class MyWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { // 原有业务逻辑,此处为挂起函数 return Result.success() } override fun onStopped() { super.onStopped() // 你现有的保存SharedPreference、上传Firebase逻辑保持不变 val sharedPreferences = applicationContext.getSharedPreferences("AppSharedPreference", Context.MODE_PRIVATE) with(sharedPreferences.edit()) { putString("working_state", "STOPPED") commit() } val db = Firebase.firestore val now = DateTime.now() val input = hashMapOf("timestamp" to now.toString(), "stopped" to "the service is somehow stopped") db.collection("test").document(now.toString()).set(input, SetOptions.merge()) } }
- 调整测试逻辑
测试手动取消时要保证任务处于运行中状态,可在
doWork中加几秒延迟预留操作时间:
override suspend fun doWork(): Result { // 加10秒延迟,方便在这段时间内点击取消按钮测试 delay(10000) // 原有业务逻辑 return Result.success() }
- 补充进程被杀场景兜底逻辑
针对杀进程无法触发
onStopped的场景,可在应用下次启动时读取WorkManager的任务历史状态,判断上次任务是否异常终止,补执行数据保存和上传逻辑。
- 优化异步操作可靠性
你现有
onStopped中的Firebase上传是异步操作,onStopped被调用后进程可能很快被销毁,异步操作大概率无法执行完成,建议将上传逻辑改为同步执行,或者额外发起一个WorkManager任务兜底上传。
内容的提问来源于stack exchange,提问作者sssbbb
相关产品推荐
相关产品推荐

