WorkManager.getInstance()。cancelAllWorkByTag()不会停止定期作业

时间:2018-09-07 08:19:28

标签: android android-jetpack android-workmanager

对于定期任务,我使用工作管理器为:

PeriodicWorkRequest.Builder wifiWorkBuilder =
                            new PeriodicWorkRequest.Builder(FileUpload.class, 15,
                                    TimeUnit.MINUTES)
                                    .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.METERED).build());
                    PeriodicWorkRequest wifiWork = wifiWorkBuilder.build();
                    WorkManager.getInstance().enqueueUniquePeriodicWork("wifiJob", ExistingPeriodicWorkPolicy.REPLACE, wifiWork);

我在该活动中有一个活动,如果用户取消选中该复选框,则会有一个复选框,然后我想停止此作业。所以我要停止工作:

WorkManager.getInstance().cancelAllWorkByTag("wifiJob");

但是在停止工作之后,我的任务也正在执行。以前我以为下一个作业可能会被执行,此后它会停止,但是在过去的1小时中它执行了4次,而作业仍在后台运行。什么是停止工作的其他方法或正确方法。

根据文档:

  

使用给定标签取消所有未完成的工作。请注意,取消是一项尽力而为的政策,已经执行的工作可能会继续运行。

这是什么意思-取消是一项尽力而为的政策,已经在执行的工作可能会继续运行。那么阻止此错误的正确方法是什么

我正在使用implementation "android.arch.work:work-runtime:1.0.0-alpha08"版 预先感谢

3 个答案:

答案 0 :(得分:5)

在创建PeriodicWorkRequest时,我添加了addTag()并使用相同的标签名来取消任务,使用它可以取消待处理的工作。所以我的代码就像:

PeriodicWorkRequest.Builder wifiWorkBuilder =
                            new PeriodicWorkRequest.Builder(FileUpload.class, 15,
                                    TimeUnit.MINUTES)
                                    .addTag("WIFIJOB1")
                                    .setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.METERED).build());
                    wifiWork = wifiWorkBuilder.build();
                    WorkManager.getInstance().enqueueUniquePeriodicWork("wifiJob", ExistingPeriodicWorkPolicy.REPLACE, wifiWork);

要停止工作,我正在使用

WorkManager.getInstance().cancelAllWorkByTag("WIFIJOB1");

答案 1 :(得分:0)

我一直在查看Android的官方文档:https://developer.android.com/reference/androidx/work/WorkManager

WorkManager支持两种类型的工作: OneTimeWorkRequest PeriodicWorkRequest

您可以使用WorkManager排队请求,如下所示:

 WorkManager workManager = WorkManager.getInstance();
 workManager.enqueue(new OneTimeWorkRequest.Builder(FooWorker.class).build());

WorkRequest具有一个关联的ID,可用于以下情况的查找和观察:

WorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class).build();
 workManager.enqueue(request);
 LiveData<WorkStatus> status = workManager.getStatusById(request.getId());
 status.observe(...);

您也可以使用ID进行取消:

WorkRequest request = new OneTimeWorkRequest.Builder(FooWorker.class).build();
 workManager.enqueue(request);
 workManager.cancelWorkById(request.getId());

在这里您可以看到取消入队作品的不同方法:

enter image description here

也许您还可以尝试使用作业的状态来取消排队或阻塞的作业:

WorkStatus workStatus = WorkManager.getInstance().getStatusById(wifiWork.getId()).getValue();
        if(workStatus.getState() == State.ENQUEUED || workStatus.getState() == State.BLOCKED){
            WorkManager.getInstance().cancelWorkById(wifiWork.getId());

        }

希望对您有帮助。

答案 2 :(得分:0)

我相信您在这里遇到的问题可以在此duplicate question中得到解决。

总而言之,如果您有一个尚未启动的挂起的工作程序,则该工作程序将被取消并且无法运行。但是,如果工作程序已经在运行,取消工作并不会以强硬方式终止工作程序-它只是将工作程序的状态标志设置为*textures[id]->variation[no];as explained in the docs。您可以自行决定delete tex;内部的取消并终止工作人员。

一种方法是通过调用CANCELLED在您的doWork方法中进行一些检查,以检查该工作程序是否已被取消。如果doWork为true,则使用isStopped()从方法中返回,而不是继续进行其余工作。