WorkManager.getInstance().cancelAllWorkByTag() not stopping the periodic job

14,294

Solution 1

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

Solution 2

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.

Solution 3

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.

Share:
14,294

Related videos on Youtube

PPD
Author by

PPD

Updated on July 05, 2020

Comments

  • PPD
    PPD almost 4 years

    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

  • PPD
    PPD almost 6 years
    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 task
  • Juanjo Berenguer
    Juanjo Berenguer almost 6 years
    I edited the code with a new suggestion using WorkStatus
  • PPD
    PPD almost 6 years
    Hi Tested with your new code but still some times it not stop the job
  • Juanjo Berenguer
    Juanjo Berenguer almost 6 years
    Hi. I will test in this weekend and if i find something that could fix it i will tell you
  • varun
    varun about 5 years
    For future readers, the method cancelUniqueWork(String workName) exists! :)
  • roghayeh hosseini
    roghayeh hosseini over 3 years
    @varun What is workerName for use in cancelUniqueWork()?
  • varun
    varun over 3 years
    @roghayeh hosseini Oh, use the name you had given when you created it with beginUniqueWork(String uniqueWorkName, ...) method.
  • Dyno Cris
    Dyno Cris about 3 years
    getInstance() is deprecated. Now need to use getInstance(context)
  • Dinith Rukshan Kumara
    Dinith Rukshan Kumara almost 3 years
    cancelAllWork() is also existed. This helped me in most cases. This will stop all remaining workers.