Android Jetpack: Introducing WorkManager
Articles Blog

Android Jetpack: Introducing WorkManager

August 22, 2019

always be in the foreground. But you still need to do
important background work like downloading updates and
syncing with your server. Now, there are
many existing APIs for this, each with their
own particular use cases. Unfortunately, when these
APIs are used incorrectly, we see this happen. To save power for
users, Android has introduced many battery-saving
features in recent releases. These features
manage and balance the power usage of apps. As a developer, you need to
work with these battery-saving features to ensure
your background tasks run across API levels. This adds code complexity. But if you don’t
do this properly, you risk your background work
not running for all users. This is where the
WorkManager library comes in. WorkManager provides a unified
solution for background work, taking Android’s power-saving
features and the user’s API level into account. It’s backwards compatible
to API level 14, part of Android Jetpack, and it runs
with or without Google Play services. These features and more make
it the recommended solution for most background
work on Android. There are two key
attributes that make a task suitable
for WorkManager– first, that the
task is deferrable, and second, that the task
needs to be guaranteed to run. Deferrable work is any task
which is still useful even if it’s not run immediately. So sending analytic
data to your server is totally deferrable work. But sending an instant
message is not deferrable. Guaranteed work
means that the task will run even if the
app process is killed or the device restarts. So a great use case
for WorkManager would be backing up
pictures to a server. This work can be deferred,
but it should also be guaranteed to run. WorkManager can be
paired with other APIs, like Firebase Cloud Messaging,
to trigger background work. So for example,
when there is data ready to sync on
your server, you can use an FCM message
to notify your app and then do the actual
syncing with WorkManager. While WorkManager is
powerful, background work isn’t a one-size-fits-all
approach. So for example, while
I’ve been talking a lot about background work,
what I don’t mean is background threading. WorkManager works
in conjunction with, but is not a replacement for,
Kotlin Coroutines, threadpools, or libraries like RxJava. WorkManager is also not
designed to trigger work at an exact time. For that, you’re going to need
to use an API like AlarmManager or start a foreground service
if your users expect your tasks to happen immediately. For a complete view of
modern background execution, check out this blog post
on the “Android Developer” blog which I have linked below. Now, let me show you how
to actually create and do some work. Let’s say that I want to upload
a photo using WorkManager. First, you define what your
task does using a worker, like this one. All the code goes into
the doWork method. Then you make a request
to do this work, using a class
called WorkRequest. As part of the WorkRequest,
you could add constraints, specify the input, and
choose to run the work once or periodically. The WorkRequest is
basically a class for configuring when and
how your task will be run. Since this is
non-repeating work, I’m going to go ahead and
use a OneTimeWorkRequest. I’ve added a constraint
here that it should only do this upload when
there’s actually network. Finally, this passes in the
URI of the photo as input data, using WorkManager’s Data Object. Once you have a WorkRequest,
you can enqueue it by calling WorkManager.enqueue. And well, that’s it. At this point, I
know that this photo will be uploaded at some point
in the future when the network constraint is met, even
if the app is closed or the phone restarts. Now, let’s say that I want
the option of updating the UI when my work finishes. I can use the method
getWorkInfoByIdLiveData to get a WorkInfo LiveData. The fact that the WorkInfo
is wrapped by LiveData makes it observable. If you haven’t used
LiveData before, you can read about it in the
documentation linked below. WorkInfo has all
of the information about the current
state of my work, including the status of the
work and the optional output. So back in doWork, I
could return an output and then add this
LiveData observation code to my UI to display the
output when available. So what’s going on behind the
scenes when you enqueue work? As mentioned,
WorkManager is backwards compatible to API
level 14 and runs without Google Play services. To ensure this, WorkManager
chooses between JobScheduler and a combination of
AlarmManager and broadcast receivers when running. To guarantee that the
work will keep running, all of that information
about enqueued work is kept in a
WorkManager-managed database so that it can be resumed
if it’s ever stopped. Now, by default, Worker does
work off of the main thread, using an executor
behind the scenes. If you want to handle
threading in some other way, there’s RxWorker and
CoroutineWorker, which are available out of the box. Or for even more control, you
can make your own worker class by extending
ListenableWorker and defining your exact threading strategy. One area where
WorkManager truly shines is when you create
chains of dependent work. Let’s say that I want to add
a filter to multiple pictures, compress those
pictures together, and then batch
upload the compressed file to share with the world. Assuming you created all
of your work requests with the appropriate
constraints, the code to create this
dependent chain of work looks like this. I enqueued the
WorkRequests in the order that I want them to run. I’ve also enqueued these
filter image WorkRequests as a list, which causes
them to run in parallel. WorkManager will take care
of passing through the output and input in a chain. So here, the output of
these filter WorkRequests will be passed as the input
of the compressed WorkRequest. There is a ton more that you
could do with WorkManager. You can specify things
like periodic work for work that needs
to run repeatedly, unique work, tagged work so
that you can query or cancel related work, and backoff
policies for retrying work. For even more features,
tips, and tricks, check out the “Working with
Work Manager” talk linked below. So to summarize, by
using WorkManager, you can enqueue one-off
and periodic tasks with constraints, chain
tasks with input and output, and run these chained tasks
in parallel or sequentially, display the state of your
tasks using observation, and customize WorkManager’s
threading strategy. WorkManager does all
of this while handling complex compatibility
issues, following system health best practices,
and guaranteeing your work will run. If you’re ready to get
working with WorkManager, I’ve linked tons of helpful
documentation, code labs, presentations, and
blog posts below. Happy coding. [JET ROARING]

Only registered users can comment.

  1. I already use the Workmanager for my production app but I noticed in Workmanager API that some Chinese ROM (MiUi, EMUI) are not able to perform a periodic work. I don't know, is this bug or some optimization in ROM but at same time stock android perform very well to perform the periodic task.

  2. Finally we don't need to code endless boilerplates trying to combine Receivers and Job Scheduler anymore… Yay!

  3. Google is finally figuring out why Windows had a task scheduler for the last 20 years. Give it 10 more years and Google might figure out why Windows hardware drivers are independent of OS updates.

  4. Question to everyone. You have a chat application that works with sockets. Steps you have to do in background. You create socket, connect it, then you create a channel and listen to this channel. When someone writes you message, channel says you have a new message from x user. After this you have to show notification and say server (send event) that you got the message. Here is it. Question to everyone. How you can realize this work in background without limitations?

  5. This library serves an important need. We used evernote/android-job to do this in past projects — this library does almost exactly the same thing. Even when workManager was in alpha it was stable (as in it didn't crash) but they were still playing with the API.

  6. Is there a possibility of Work Manager running when the app is in the foreground and meets all the constraints specified???

  7. This will solve
    java.lang.IllegalStateException: Not allowed to start service Intent app is in background Error

  8. Good stuff but getWorkInfoIdByLiveData sounds like an anti-pattern method, if I'd review the PR I'd suggest getWorkStateById instead. As users of the API we are requesting a state and for us it doesn't matter if Google uses LiveData behind the rug, if the method returns an Observable we already know enough, there's no need to add LiveData suffix on this method.

  9. For the God sake !

    Why do we need to connect to network or charging (Constrains) to upload photos !. The work will be cancelled if disconnects from network and later retry once connects !?. Why the work should be deferrable in this case .

    Even noticed the same in job schedulers !!!!! . If you don't set constrains in JobSchedulers ,I will be run time error . But in workmanger the work will be executed right away if no constrains right !?.

  10. Is it possible the periodic Task time interval 15 seconds in workManager.?
    I found workManager periodic task minimum time interval is 15 minutes. 🙁

  11. Hello. I am looking for a google play console with live game applications (the older the better). Who is ready to sell along with the source (developer key, application project)? Conditions in private messages

  12. Was Firebase removed from gradle as optional dependency that WorkManager can use? I don't see it on the docs anymore…
    Also, it seems many classes were changed over time or removed. What should I do if I want to migrate from 1.0.0-alpha09 ?

  13. It's not validate code. It wont work Bla bla bla… We google we don't make mistakes in a presentation… Fun)… In Worker we must pass Context which is "c" parameter not ctx….

  14. Can you explain 4:14?

    "Now by default, worker does work off of the main thread using an executor behind the scenes."

    But the slide says:
    "doWork() called on background thread by Executor"

    What kind of work is WorkManager doing on the main thread if the executor is running on a background thread?
    What's the disadvantages to it being on the main thread?

  15. How does workmanager will work even if app is closed?????? will it work??? from background without running app????????? will it sendthe data to server???????

Leave a Reply

Your email address will not be published. Required fields are marked *