Use WorkManager for immediate background execution
Some tasks just shouldn’t be deferred
When you have to execute long running tasks while your app is in the background, you will encounter restrictions to background execution that were introduced with Android 8.0. These restrictions incentivize developer behavior that improves the user’s experience of the entire platform.
To make it easier to accommodate different use cases, we also improved the developer experience when working with background restrictions by adding functionality to WorkManager.
We recommend you use WorkManager to execute long running immediate tasks.
Follow along and learn about the benefits of using WorkManager for immediate execution of long running tasks and how to set everything up.
Introduction to the API
Starting with WorkManager version 2.3.0, every Worker has access to methods to run tasks in a foreground service. The Worker base class,
ListenableWorker, provides a new
This post uses
CoroutineWorker for demonstration purposes. In CoroutineWorker,
setForegroundAsync() is wrapped in a suspending
setForeground() function. The class also provides the suspending
doWork function which allows running code off the main thread. But all of this post’s content is also applicable to the corresponding functions for other Worker classes.
When you use setForeground(Async), the scheduled task will be run in a foreground service, immediately, once the constraints are met. As a bonus, WorkManager takes care of handling the service’s lifecycle for you. And, the ten minute time limit for background work won’t apply to the work you’re doing in a worker running in a foreground service.
Get started with immediate execution
Let’s take a look at how to make an existing worker execute work in a foreground service.
Our starting point is a very simplified
doWork() function. Code is executed asynchronously, and depending on whether it succeeds or not, the corresponding
Result is returned.
doWork() you will also tell WorkManager that the task should be run immediately and in a foreground service.
To do this, you have to create a
ForegroundInfo object and provide it to
setForeground(). ForegroundInfo takes a notification id as well as the
Notification that will be displayed as parameters.
This information is used to set up and run the foreground service once constraints are met.
Set up ForegroundInfo
Correctly setting up ForegroundInfo is as easy as 1, 2, 3:
- Create a Notification
- Create a Notification Channel
- Provide the Notification to ForegroundInfo
In the code below,
createNotification(), which in turn populates the notification and creates the corresponding channel.
Run work in a foreground service
Now let’s bring things together. Since we already have an implemented
doWork() function, we can call
setForeground() and pass required information by calling
setForeground()before your long running task kicks off.
Otherwise your worker will be treated as non-foreground service until
setForeground()has been called, which might result in unwanted results such as work being cancelled.
🐾 Next steps
Now that you know when and how to use long running workers you can go ahead and get started implementing them in your app.
🔖 For a detailed guide on long running workers and foreground services, take a look at the advanced WorkManager guide for long running workers.
🐛 Report any issues you face on the Google IssueTracker. This will help us prioritize features and bug fixes as they come in.
📝 Let me know how running immediate tasks works for you in a comment below or on Twitter.