Cancelling and stopping work

If you no longer need your previously-enqueued work to run, you can ask for it to be cancelled. The simplest way to do this is by cancelling a single WorkRequest using its id and calling WorkManager.cancelWorkById(UUID):

Kotlin

WorkManager.cancelWorkById(workRequest.id)

Java

WorkManager.cancelWorkById(workRequest.getId());

Under the hood, WorkManager will check the State of the work. If the work is already finished, nothing will happen. Otherwise, its state will be changed to CANCELLED and the work will not run in the future. Any WorkRequests that are dependent on this work will also be CANCELLED.

In addition, if the work is currently RUNNING, the worker will also receive a call to ListenableWorker.onStopped(). Override this method to handle any potential cleanup. We discuss this more at length further below.

You can also cancel WorkRequests by tag using WorkManager.cancelAllWorkByTag(String). Note that this method cancels all work with this tag. Additionally, you can cancel all work with a unique name using WorkManager.cancelUniqueWork(String).

Stopping a running worker

There are a few different reasons your running worker may be stopped by WorkManager:

  • You explicitly asked for it to be cancelled (by calling WorkManager.cancelWorkById(UUID), for example).
  • In the case of unique work, you explicitly enqueued a new WorkRequest with an ExistingWorkPolicy of REPLACE. The old WorkRequest is immediately considered terminated.
  • Your work's constraints are no longer met.
  • The system instructed your app to stop your work for some reason. This can happen if you exceed the execution deadline of 10 minutes. The work is scheduled for retry at a later time.

Under these conditions, your worker will receive a call to ListenableWorker.onStopped(). You should perform cleanup and cooperatively finish your worker in case the OS decides to shut down your app. For example, you should close open handles to databases and files at this point, or do so at the earliest available time. In addition, you may consult ListenableWorker.isStopped() whenever you want to check if you've already been stopped. Even if you signal completion of your work by returning a Result after onStopped() is called, WorkManager will ignore that Result because the worker is already considered stopped.

You can see examples of how to handle onStopped() in the Threading in WorkManager section.