How Scheduling work with new Android Jetpack component “WorkManager”?

Schedule Task with Android WorkManager

As time move, Android also got evolved, many things got changed in it, but certain things you always be rely on is Android fundamentals that still exist and not changed. But what inside it always getting updated.

Android Fundamentals

Let’s see how’s few of Android Fundamentals get evolved.

1) Java Language Syntax “Kotlin”

2) UI logic goes in the Activity “View Models”

3) Service for background processing “Job Scheduler”

4) Monitor system events with Receivers “Job Scheduler”

5) Content Providers for database access “Room Database”

Now onwards Job Scheduler already deprecated for next version of Android so now we have WorkManager instead. And I really don’t want to waste time here to write history of android background service APIs, But for those who wanted to dive into that we have below nice article available to refer, which gives you overall idea before Android P which scheduler task you can use for your app.

The WorkManager API makes it easy to specify deferrable, asynchronous tasks and when they should run. These APIs let you create a task and hand it off to WorkManager to run immediately or at an appropriate time. For example, an app might need to download new resources from the network from time to time. Using these classes, you can set up a task, choose appropriate circumstances for it to run (like “only while device is charging and online”), and hand it off to WorkManager to run when the conditions are met. The task is still guaranteed to run, even if your app is force-quit or the device is rebooted.

WorkManager chooses the appropriate way to run your task based on such factors as the device API level and the app state. If WorkManager executes one of your tasks while the app is running, WorkManager can run your task in a new thread in your app’s process. If your app is not running, WorkManager chooses an appropriate way to schedule a background task — depending on the device API level and included dependencies, WorkManager might use JobScheduler, Firebase Job Dispatcher, or AlarmManager. You don't need to write device logic to figure out what capabilities the device has and choose an appropriate API; instead, you can just hand your task off to WorkManager and let it choose the best option.

  1. Guaranteed and constraint-aware execution
    There are some circumstances everytime while scheduling background/long running task like network availability, device in doze mode (Like, if your app is in DOZE mode then it wouldn’t execute, it wouldn’t wake up your phone just to do that work), sync data only when charging so many but WorkManager is taking care of all these constraints and give app guaranteed to be execute even if device get rebooted or app get exited without executing that task.
  2. Backwards compatible with or without Google play service
    So it has benefit over the Firebase Job Dispatcher which backwards compatible but not work for device without Google play service.
  3. Queryable
    This is not limited to only scheduling the task but If you having queued some work, you can actually check it’s state as well whether it is running right now?, Has it succeeded or failed.
  4. Chainable
    You can create drafts of work so like if you have work A depending on B & C which in turns depends on work D you can do it with WorkManager, more detail of chaining given below in this article.
  5. Opportunistic
    It means that WorkManager will try to execute your work in your app as soon as the constraints are met without actually needing Job Scheduler to step in (call you up and wake you up), it doesn’t wait for job scheduler to batch at work if your process is up and running already

Let’s go more in technical detail WorkManager has base classes which exactly doing the scheduling, Have look each of them.
Worker : Specifies what task you need to perform. The WorkManager APIs include an abstract Workerclass. You extend this class and perform the work here. This is the class that does the work and this is where we will write
most of our business logic.
WorkRequest : Represents an individual task. At a minimum, a WorkRequest object specifies which Worker class should perform the task. However, you can also add details to the WorkRequest object, specifying things like the circumstances under which the task should run. Every WorkRequest has an autogenerated unique ID; you can use the ID to do things like cancel a queued task or get the task's state. WorkRequest is an abstract class; in your code, you'll be using one of the direct subclasses
A) OneTimeWorkRequest :
A class that represents a request for non-repeating work. And I have use this class to build the Worker thread in all my below examples.
B) PeriodicWorkRequest: A class that represents a request for repeating work. This class need more detail explanation so I will try to add this to my next article.
Below given one example for uploading image to server, and describing above classes and its usage.

WorkResult has three values
1) SUCCESS
2) FAILURE
3) RETRY : Means encountered a transient error i.e if device lost network connection in the middle so we will have to retry after little bit some back off

Now let’s create one time work request in queue to upload a photo

How to use constraints with WorkRequest

Now, let’s observing the status of work. Each request has unique id which will be pass into workManger object into getStatusById method to get Live data of that request. And if you have idea about architecture components live data is a life cycle aware observable so now you must hook it to that observable and you can write code to hide the progressbar once the work finished.

Have fast look to what WorkStatus is
WorkStatus : A simple class with the id of a WorkRquest and have 6 state which describe current state of execution
· ENQUEUED
· RUNNING
· SUCCEEDED
· FAILED
· BLOCKED
· CANCELLED

This is most attractive features of WorkManager I would like to emphases here with some use cases. all below use cases will be taken same example as above to upload a files to server.

Case 1
In this problem wanted to upload huge video to server so we need to first compress it and then upload but both eligible for background work because they’re time consuming things

Huge Video File => Compress => Upload

Let’s do it in fluent way

Case 2
In this problem upload multiple photo to server parallel, they may not be run in parallel but its depending on your device and the executor being used

Multiple Photos => upload

Case 3
Here is the more complex problem first filter your multiple photos (any kind of filter like grayscale filter or sepia filter) then compress and then you want to upload them, how to do this…

Multiple Photos -> Filter -> Compress → Upload

Geek | Android Developer | AndroidThings & IoT Learner <Raspberrypi> <Arduino> <ESPRESSIF>

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store