WorkManager.getInstance().cancelAllWorkByTag() not stopping the periodic job
Asked Answered
G

3

29

for periodic task I am using work manager as:

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);

I have one activity in that activity one check box is there if user unselect checkbox then I want to stop this job. So I am stopping job like:

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

But after stopping job also my task is executing. Previously I thought might be next job will be executed and after that it will stop but in last 1 hour it executed 4 times and still job is running in background. What is other way or correct way to stop job.

as per Docs:

Cancels all unfinished work with the given tag. Note that cancellation is a best-effort policy and work that is already executing may continue to run.

What is the meaning of this - cancellation is a best-effort policy and work that is already executing may continue to run. So what is the correct way to stop this

I am using version implementation "android.arch.work:work-runtime:1.0.0-alpha08" Thanks in advance

Gunwale answered 7/9, 2018 at 8:19 Comment(0)
G
41

While creating PeriodicWorkRequest i had added addTag() and to cancel task used same tag name, using this it cancel pending work. So my code is like:

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);

To stop job I am using:

WorkManager.getInstance().cancelAllWorkByTag("WIFIJOB1");
Gunwale answered 10/9, 2018 at 7:17 Comment(5)
For future readers, the method cancelUniqueWork(String workName) exists! :)Eagle
@Eagle What is workerName for use in cancelUniqueWork()?Carpio
@roghayeh hosseini Oh, use the name you had given when you created it with beginUniqueWork(String uniqueWorkName, ...) method.Eagle
getInstance() is deprecated. Now need to use getInstance(context)Tybalt
cancelAllWork() is also existed. This helped me in most cases. This will stop all remaining workers.Marthena
W
12

I believe the problem you are having here is answered in this duplicate question.

In summary, if you have a pending worker which hasn't started yet, the worker will be cancelled and will not run. However if the worker is already running, cancelling work does not terminate the worker in a hard fashion - it simply sets the state flag of the worker to CANCELLED, as explained in the docs. It is up to you to handle the cancellation inside your doWork and terminate the worker.

One way to do this is to put a few checks in your doWork method to check if the worker has been cancelled, by calling isStopped(). If isStopped is true, return from the method with a Result instead of continuing with the rest of the work.

Weingarten answered 4/7, 2019 at 16:29 Comment(0)
T
2

I've been checking the official Android docs: https://developer.android.com/reference/androidx/work/WorkManager

There are two types of work supported by WorkManager: OneTimeWorkRequest and PeriodicWorkRequest.

You can enqueue requests using WorkManager as follows:

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

A WorkRequest has an associated id that can be used for lookups and observation as follows:

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

You can also use the id for cancellation:

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

And here you can see a different ways to cancel a enqueued work:

enter image description here

Maybe you also can try to cancel a enqueued or blocked job using the State of the job:

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

        }

I hope it helps you.

Teth answered 7/9, 2018 at 8:32 Comment(4)
Thanks for reply, I want to upload files after every 15 min therefore I had used PeriodicWorkRequest. But using checkbox user can cancel uploading file at any time when he wants. So to cancel this I am using cancelAllWorkByTag () and pasing same tag which was used at time of creation of task. But its not getting cancelled the pending taskGunwale
I edited the code with a new suggestion using WorkStatusTeth
Hi Tested with your new code but still some times it not stop the jobGunwale
Hi. I will test in this weekend and if i find something that could fix it i will tell youTeth

© 2022 - 2024 — McMap. All rights reserved.