I need to cancel/remove my work when it meets a condition. I`ve read that there is a method onStopped() that can be overridden, but it is for simple :Worker and not for CoroutineWorker.
My worker:
class MyJob(appContext: Context, params: WorkerParameters) :
CoroutineWorker(appContext, params) {
override suspend fun doWork(): Result {
val itemId = inputData.getLong("item_id",0)
val itemDao = ItemDB.getInstance(applicationContext).itemDao()
val itemRepository = ItemRepo(itemsDao)
val item = itemRepository.getItemById(itemId)
val newValue = item.a + item.b
item.a = newValue
itemRepository.updateItem(item)
if(item.a == item.c){
WorkManager.getInstance(applicationContext).cancelUniqueWork("TEST_WORKER")
}
return Result.success()
}
}
EDIT: My mistake, i forgot to mention that this is a unique periodic work.
您可以尝试通过返回来取消工作Result.failure()
;所以你可以根据你的情况添加它
if(item.a == item.c){
//Cancel work
return Result.failure()
}
现在您需要在您的活动/片段中收听工作结果;由于您没有提供这部分代码,我会做一些假设,并用生命周期观察模型听取工作结果
// instantiate periodic work
final PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(...).build();
// schedule the work
WorkManager.getInstance(this).enqueue(workRequest);
// observe the work
WorkManager.getInstance(this).getWorkInfoByIdLiveData(workRequest.getId())
.observe(this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
if (workInfo.getState() == WorkInfo.State.FAILED) {
// cancelling work
WorkManager.getInstance(MainActivity.this).cancelWorkById(workRequest.getId());
}
}
});
但它仍然会被排队。它将运行,除了返回失败之外什么都不做。
所以基本上这意味着不断观察所有工人并删除失败的工人......我考虑过。但是,如果我只是取消其内部的工人怎么办?这是一种不好的做法吗?因为我刚刚测试过,它工作得很好。检查更新的问题...
@NickWilde .. 问题是你需要取消工人并在 内提出doWork(),我的意思是在执行你的工作期间,所以你需要观察你的工作直到满足那个条件; 这就是我取消它的原因;
@NickWilde 可能有更好的解决方案,但我没有测试它,您可以拥有一个由启动定期工作的活动实现的侦听器,并以某种方式将该侦听器的实例传递给您的 Worker,并触发一次回调你需要取消你的工作,然后 WorkManager.getInstance(MainActivity.this).cancelWorkById(workRequest.getId());在活动的回调中使用