Affiliate links on Android Authority may earn us a commission.Learn more.
Scheduling background tasks with Jetpack’s WorkManager
August 21, 2025
Android apps can work in the background in sever ways, but sometimes too much choice can be a bad thing. Android has a range of APIs and components for scheduling background work, and the “correct” approach can vary depending on the version of Android, and other factors like whether the device has access toGoogle Play Services.
For example, you may use JobScheduler to schedule background work, but only on Android 5.0 (API 21) and later. If you want your app to be compatible with earlier versions of Android, you could use Firebase JobDispatcher, but there’s a catch: JobDispatcher requires Google Play Services, and there’s plenty of Android users who don’t have access to Google Play Services, especially in China.

WorkManager is a new library for making scheduling and managing background work much less painful. Announced atGoogle I/O 2018as part of Jetpack, it provides a new, straightforward way to handle background tasks — by doing all the hard work for you.
Let’s take a look at how to use WorkManager to schedule background work, run tasks in parallel, and improve the user experience by specifying different conditions that need to be met before a task can run.

Exploring Jetpack: What is WorkManager?
WorkManager is a job dispatching service scheduling tasks, and then forget about them. Once a task is scheduled, WorkManager will run it regardless of whether the user navigates away from the related screen, exits your application, or even reboots their device. This makes it ideal for tasks requiring guaranteed execution.
By default, WorkManager runs each task immediately, but you can also specify the conditions a device needs to fulfill before the task can run, including network conditions, charging status, and the amount of storage space available on the device. For example, you can reduce the amount of mobile data your app consumes by delaying data-intensive tasks until the device is connected to an unmetered network, or only perform battery-intensive tasks when the device is charging.

If WorkManager executes while your application is running, it’ll perform its work in a new background thread. If your application isn’t running, WorkManager will choose the most appropriate way to schedule the background task, based on factors such as the device’s API level and whether it has access to Google Play Services. In this way, WorkManager can provide the functionality of APIs like JobScheduler without requiring you to check the device’s capabilities and provide alternative solutions depending on the results. Specifically, WorkManager uses JobScheduler on devices running API 23 and later. On API 14-22 it’ll use either Firebase JobDispatcher, or a custom AlarmManager and BroadcastReceiver implementation, if Firebase isn’t available.
Since WorkManager is part of Jetpack, it’s backwards compatible to API level 14, so it’s ideal for scheduling background tasks across earlier versions of Android where solutions such as JobScheduler aren’t supported. It can also function with or without Google Play Services, so you can be confident your app will behave as expected, even in parts of the world where access to Google Play Services is restricted.

Once WorkManager is stable it’ll be the recommended task scheduler for tasks that require guaranteed execution. WorkManager isn’t intended to be a catch-all solution for every task you need to run off the main thread, so if a task doesn’t require guaranteed execution then you should use intent services or foreground services instead.
One time task, or recurring?
WorkManager supports two types of work:
OneTimeWorkRequest
To schedule a task that executes one time only, you need to create aOneTimeWorkRequestobject, and then enqueue your task:
Since we haven’t specified any constraints, this task will run immediately.

PeriodicWorkRequest
You’ll want to repeat some tasks, like syncing your application’s data with a server once per day.
To create a recurring task, you usePeriodicWorkRequest.Builderto build a PeriodicWorkRequest object, specify the interval between each task, and then enqueue the PeriodicWorkRequest. Here we’re creating a task that will run once every 12 hours:
Making the switch to WorkManager
Let’s look at how you’d implement a few different WorkManager workflows, including how to create tasks that only run when specific constraints are met.
I’m going to create an app consisting of a button that will pass a task to WorkManager when clicked. To keep things simple, this task will print a message to Android Studio’s Logcat, but you can swap the Logcat portions of the code for any other task you had in mind.
Create a new project, then open itsbuild.gradlefile and add theWorkManagerlibrary as a project dependency:
Creating your app’s layout
Next, create a layout consisting of the button to trigger ourWorkManagerflow:
Creating one time WorkRequests
In ourMainActivity, we need to perform the following:
Here’s the finishedMainActivityclass:
What task should WorkManager perform?
Next, you’ll need to specify the taskWorkManagershould perform in the background, by extending from the Worker class and overriding itsdoWork()method.
To create this worker class:
Run your project on an Android device or Android Virtual Device (AVD), and give the “One Time Request” button a click. This task should immediately run in the background and print the “doWork called” message to Android Studio’s Logcat.
Setting some constraints: Controlling when a task runs
By default, WorkManager will perform each task immediately, but you can also specify constraints that need to be met before the work gets done. You can use it to delay intensive tasks until the device is idle, to avoid negatively impacting the user experience.
To set some rules about when a task should run, you’ll need to create a Constraints object usingConstraints.Builder, and then specify the Constraint(s) that you want to use, such as.setRequiresDeviceIdle:
Next, you’ll need to pass the Constraints object to yourWorkRequest:
WorkManager will then take these constraints into consideration, when finding the perfect time to run your task.
Let’s update our project, so the message is only printed to Logcat when the device enters a low battery state.
Wherever possible you should test WorkManager on an Android Virtual Device (AVD), as it’s usually easier to simulate different device conditions, rather than waiting for them to occur on your smartphone or tablet naturally.
To test this particular project’s battery constraint, follow these steps:
Next, repeat this process with a low battery level:
This is also a good opportunity to see how WorkManager can run scheduled tasks, even when the user has exited your application:
Get specific: Setting multiple constraints
Sometimes, you’ll have a task that should only run under very specific circumstances, for example you might want to delay an unusually intensive task until the device is charging, connected to the Internet and standing idle.
you’re able to use WorkManager to build chains of constraints. Here we’re creating a task that will only run when the device is connected to an unmetered network and a power outlet:
you’re able to put this application to the test by only meeting one of these constraints and checking whether the message still appears in Android Studio’s Logcat:
Chaining tasks with WorkContinuation
Some of your tasks may depend on the successful completion of other tasks. You might want to upload your application’s data to a server, but only after that data has been compressed.
You can create chains of tasks, by calling WorkManager’sbeginWith()method and passing it the first task in the chain. This will return aWorkContinuationobject, which allows you to chain subsequent tasks, via theWorkContinuation.then()method. Finally, when enqueue this sequence usingWorkContinuation.enqueue(),WorkManager will run all of your tasks in the requested order.
Note you cannot enqueue periodic and one-time work in the same queue.
To create a chain, we need a second Worker class:
To make it clear which task is running, I’m going to update the MyWorker class so that it prints a different message to Logcat:
Then, add the following to your MainActivity:
Click the app’s “One Time Request” button, and your Logcat output should look something like this:
D/MyWorker: My first worker calledD/WorkerWrapper: Worker result SUCCESSD/WorkerWrapper: Setting status to enqueuedD/MyWorker: My second workerD/WorkerWrapper: Worker result SUCCESS
Alternatively, you could run these tasks in parallel:
If you need to create more complex sequences, then you can join multiple chains using theWorkContinuation.combine()method.
Different constraints, for different tasks
you may combine constraints and chained tasks to create a sequence where each task waits until a different set of conditions are met. Our application could compress its data whenever storage space is low, and then wait until the device is connected to an unmetered network, before syncing this newly-compressed data with the server.
Here, I’ve updated my MainActivity so that request1 only runs when the device is charging, and request2 only runs when there’s an active network connection:
To help us see what’s happening, I’ve updated the messages MyWorker and MySecondWorker print to Logcat:
MySecondWorker:
Wrapping up
So that’s how to use the new WorkManager API to schedule background work, including running tasks in parallel, creating chains of related tasks, and using constraints to specify exactly when a task should run.
Now that you’ve seen WorkManager in action, do you think it’s an improvement on Android’s previous schedulers? Let us know in the comments below!
Thank you for being part of our community. Read ourComment Policybefore posting.