WorkManager Tutorial for Android: Getting Started
In this WorkManager tutorial for Android, you’ll learn how to create background tasks, how to chain tasks, and how to add constraints to each task. By Fernando Sproviero.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
WorkManager Tutorial for Android: Getting Started
30 mins
- Understanding Background Work
- Types of Background Work
- Why WorkManager?
- Knowing When to Use WorkManager
- Getting Started
- Setting Up the WorkManager Library
- Understanding WorkManager Classes
- Creating Your First Background Task
- Writing the FilterWorker Code
- Instantiating and Configuring the Worker
- Checking the Results
- Chaining Tasks
- Writing the CompressWorker Code
- Chaining FilterWorker with CompressWorker
- Checking the Results
- Cleaning the Worker and Uploading the ZIP
- Checking the Results
- Starting Unique Work
- Replacing Existing Work of Picked Photos
- Observing Work
- Tagging a WorkRequest and Observing It
- Checking the Results
- Canceling Work
- Canceling the Picking Photos Work Sequence
- Understanding Constraints
- Adding a Network Connection Constraint
- Testing the Network Constraint
- Where to Go From Here?
Observing Work
WorkManager also allows you to observe the progress of each work instance using the following:
-
getStatusById()
: Use this to get a LiveData object containing the WorkStatus for the WorkRequest with a given ID. -
getStatusesByTag()
: Returns a LiveData object containing the list of WorkStatus objects for the specified tag. This is possible because you can tag multiple WorkRequests with the same name. -
getStatusesForUniqueWork()
: This will also return a LiveData object containing the list of WorkStatus objects that have the same unique work name.
Tagging a WorkRequest and Observing It
You’ll observe the work of the requests to toggle a progress bar and a cancel button. Open MainActivity and add a tag to the uploadZip work request using a new constant WORK_TAG
:
class MainActivity : AppCompatActivity() {
companion object {
...
private const val WORK_TAG = "WORK_TAG"
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
...
val uploadZip = OneTimeWorkRequest.Builder(UploadWorker::class.java)
.addTag(WORK_TAG)
.build()
After you’ve added a tag to the worker, you can observe its status. Now, add the following method to MainActivity, which will do just that:
...
import android.arch.lifecycle.Observer
...
private fun observeWork() {
val statuses = WorkManager.getInstance().getStatusesByTag(WORK_TAG)
statuses.observe(this,
Observer<List<WorkStatus>> { workStatusList ->
val currentWorkStatus = workStatusList?.getOrNull(0)
val isWorkActive = currentWorkStatus?.state?.isFinished == false
val uploadVisibility = if (isWorkActive) View.VISIBLE else View.GONE
uploadGroup.visibility = uploadVisibility
})
}
getStatusesByTag()
returns a LiveData object to which you attach an Observer. When you get an update on the status from the WorkManager, you check if it’s active or not. Since you’ve tagged only one worker, you can take the first item from the list (if it exists) and check its state. If it’s not finished, you show a progress bar and a cancel button. Otherwise, you hide them.
Now, at the bottom of the onCreate()
lifecycle method in MainActivity, add a call observeWork()
.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initUi()
requestPermissionsIfNecessary()
observeWork()
}
Checking the Results
Build and run the app. Once you start uploading images, you’ll see the progress bar and the cancel button. The cancel button doesn’t do anything yet, but you’ll fix that soon.
Canceling Work
WorkManager allows you to cancel work in several ways:
-
Unique work: If you started unique work with a unique work name, then you can just call
cancelUniqueWork()
and pass the name as parameter. -
By tag: When you tag one or more WorkRequests, you call
cancelAllWorkByTag.
-
By ID: If you have the ID of the WorkRequest and want to cancel it, you call
cancelWorkById()
.
Since you're using unique work, you'll cancel it using the unique work name.
Canceling the Picking Photos Work Sequence
In MainActivity and add the following snippet inside the initUi()
method:
cancelButton.setOnClickListener {
WorkManager.getInstance().cancelUniqueWork(UNIQUE_WORK_NAME)
}
Build and run the app, select some photos and then cancel the work requests using the cancel button.
Understanding Constraints
Some work cannot be done without a certain set of conditions. For example, work may only run if your device is not low on storage, is charging, etc. You can add constraints like these to any of your tasks. It makes sense to add a network-related constraint to the UploadWorker, because you cannot upload unless there is a stable connection.
Adding a Network Connection Constraint
In MainActivity onActivityResult()
, modify uploadZip
to the following:
val uploadZip = OneTimeWorkRequest.Builder(UploadWorker::class.java)
.setConstraints(Constraints.Builder().setRequiredNetworkType(
NetworkType.CONNECTED).build())
.addTag(WORK_TAG)
.build()
As you can see, you've configured the upload request to only run if the device is connected to the network, otherwise it will not run until the condition is met. This is really convenient because you don't have to implement the connection listeners and do the checks yourself.
Testing the Network Constraint
Run the app. Set the emulator/device into Airplane mode. Pick photos from your library and open the Logcat console. You should see that the UploadWorker will not run (filter the console for onResponse like you did before and check the timestamp on any results). Only after it receives a network connection will it upload the file. You can make sure this happens by taking a look at the console once again, after disabling Airplane mode.
Where to Go From Here?
Congratulations! You’ve just learned the basics of WorkManager.
You can download the final version of the project using the Download materials button at the top or bottom of this tutorial.
Here are some great references to learn more about the subject:
- Official Docs: You can find them here.
- Official Reference: Browse the reference here.
- The background guide will help you choose the best way for your app to perform operations in the background.
- Watch the Google I/O 2018 session.
- There's a Google codelab that you might want to check out.
- Listen to the Android Developers Backstage — WorkManager podcast episode.
- Because this library is in an alpha stage, you may find bugs. Report them in the issue tracker and have a look at the release notes for any news on WorkManager or the other Android architecture components.
- Android Background Course: Check this great course here that covers not only WorkManager but also other ways to execute background tasks.
Feel free to share your feedback, findings or ask any questions in the comments below or in the forums. I hope you enjoyed this tutorial on WorkManager!