Image from https://www.pexels.com/photo/man-building-architect-joy-33343/

On 05 March 2019 Google announced the release of Android Jetpack WorkManager 1.0 Stable. We are going to try to explain how to use WorkManager and why it is a good option to execute tasks in the background.

Usually, you need to execute on a background thread because the task is an expensive operation — like applying filters to a bitmap — or the task depends on a network request.

Until now, when you would like to execute a long-running operation in the background, you have these options:

ThreadPools , RxJava or Coroutines

, or ForegroundService

JobScheduler, Firebase JobDispatcher, and Alarm Manager + Broadcast receivers.

Now you have the WorkManager, a new simpler option with more options to guarantee battery consumption and, for example, to run it only if you are connected to a Wi-Fi network.

WorkManager is intended for tasks that are deferrable — that is, not required to run immediately — and required to run reliably even if the app exits or the device restarts.

Compatible API Level 14+

Runs with or without Google Play Services

Gradle Dependency

First of all, to use it you have to add this dependency to your build.gradle file:

Gradle dependencies

Constraints 🔋 📡

A worker’s constraints specifies the requirements that need to be met before be executed. These constraints can be related to network, battery or storage:

getRequiredNetworkType(): you can specify the NetworkType

requiresBatteryNotLow()

requiresCharging()

requiresDeviceIdle()

requiresStorageNotLow()

For instance, we can create a constraint object indicating that it is needed to be connected to the Internet and the device is charging (later we indicate how to put these constraints to your worker):

Constraints example

Create your first Worker 👷

To create your worker, you have to extend the Worker class and override doWork() method, and as a result you have to indicate how the task was finished:

finished successfully via Result.success()

failed via Result.failure()

needs to be retried at a later time via Result.retry()

Create your Worker

Execute your Worker 👷🏗️🏢

To execute your worker you have to create a WorkRequest, it defines how and when work should be run. This task may be one-off (OneTimeWorkRequest) or periodic(PeriodicWorkTimeRequest).

And now, we can add to this workRequest your constraints, and if input data is needed you can attach it to its execution.

⚠️ If you want to create a PeriodicWorkRequest you must take into account the time between executions, since there is a minimum time of 15 minutes. For instance, if a periodic time of 1 minute is set, the system will change it to 15 minutes.

W/WM-WorkSpec: Interval duration lesser than minimum allowed value; Changed to 900000

Initial Delay 🔜

When your create your workRequest you can specify a initial delay. When all constraints will be satisfied, the worker will start after this initial delay.

Retries and Backoff Policy 🔙

If you require that your worker will be executed again, you can return Result.retry() from your worker. Your work is then rescheduled with a backoff delay and policy. You can specify it calling the method setBackoffCriteria() .

Cancel your Work 🛑

If you tagged your work, you can cancel it calling WorkManager.cancelAllWorkByTag(String) and all your worker with this Tag will be cancelled.

Getting Worker’s Status & OutPut Data

Sometimes it is possible that you want to get the status of your worker in your app. To get it, you have to call the method WorkManager.getWorkInfosByTagLiveData(String) indicating the worker’s tag you want to observe.

To send the result from your worker to your observer, you can set it in the result response:

I hope this article helps you to understand better this feature, and if you have some question or something to improve, do not hesitate to comment below.

More info:

If you want to check an example, I have created a GitHub Repository with some examples using WorkManager: