This article provides an overview of WorkManager, a Jetpack library for managing deferrable and guaranteed background work in Android, and demonstrates how to use it with RxJava2 and Kotlin Coroutines.
Abstract
The article begins by explaining the problem of battery draining activities in Android and how WorkManager provides a unified solution to run background tasks. It then covers the basics of WorkManager, including its integration, constraints, and types of work requests. The article also demonstrates how to create a basic worker, use useful features of WorkManager, and observe its status. The article then shows how to use WorkManager with RxJava2 and Kotlin Coroutines, and provides a real-time example of syncing data from local DB to remote server using WorkManager.
Opinions
The author believes that WorkManager is a viable solution to do background tasks in Android.
The author emphasizes the importance of understanding how LiveData works in Android to observe the status of WorkManager.
The author suggests using Periodic Work Request to sync local DB data to remote servers in every 12 hours.
The author recommends watching a video, reading official documentation, and integrating Dagger with WorkManager for further learning.
WorkManager- jetpack android library
WorkManager basics, how to use WorkManager with Rxjava2 & Kotlin Coroutines
Learn how to handle real-time work with workmanager.
One thing that constantly changing in the android environment is how we handle background tasks. This is because when the number of apps increased in the phone, number of background tasks will also increase, most of the apps won’t check for battery health before starting their job which leads to drain the battery in a short time.
Problem
To control battery draining activities android released battery saving features like App stand by, limit implicit broadcasts, Background service limits, more broadcast limits, Battery saver and much more. As an Android developer, you should work with this battery saving features across API levels. If you don’t do this properly you risk your background tasks not running in all devices.
Solution
This is where WorkManager comes in; WorkManager provides a unified solution to run your background tasks. WorkManager is a jetpack library for managing deferrable and guaranteed background work.
Deferrable: Task can run later & still be useful like sending analytics to your server.
Guaranteed: Task can run even if your app is not running or even after phone restarts like sending large files to your server.
WorkManager is
Compatible to API level 14.
Runs with/without Google play services.
With all the above features of workmanger, it has become a viable solution to do background tasks. Now that we know why to use workmanager let’s see how to use it.
WorkManager Integration
WorkManager is a jetpack library and it’s been constantly updating to new versions when this article is written “2.1.0” is the latest stable version.
api"androidx.work:work-runtime-ktx:2.1.0"
Things to know before using WorkManager
There are two things you should know before using workmanager, they are constraints and types of work requests.
Constraints: Constraints are nothing but a way to communicate workmanager that system should satisfy certain conditions to execute a work request. This conditions can be anything like system should have an internet connection, the system shouldn’t be in battery saver mode, etc.
Work Requests: There are two types of work request, they are OneTime and Periodic work requests.
One-Time Work Request: By the name itself, we can say that this request executes only once.
Periodic Work Request : This request executes periodically once we start worker. We have to mention a certain time interval between executions while building a worker object.
Basic Worker
To create a worker, extend the class with worker and import the method doWork() which runs in the background provided by workmanager. Below sample is a simple worker whose task is to upload a picture to the server.
The return type Result from doWork() informs the workmanager whether the work is
finished successfully via Result.success()
failed via Result.failure()
needs to be retried at a later time via Result.retry()
After creating the worker, based on your requirement create oneTime or periodic work request and enqueue with workmanager as shown below.
Useful features of WorkManager
1. Delay
If your work has no constraints or that all the constraints are met when your work is enqueued, the system may choose to run the task immediately. If you do not want the task to be run immediately, you can specify your work to start after a minimum initial delay.
2. Defining input for your task
What if the worker needs some data to start, like image URL required for the above worker to download the image.
Input and output values are stored as key-value pairs in a Data object. The code below shows how you can set input data in your WorkRequest.
We can access the data sent to the worker using getInputData() as shown below
You can tag a request with a long string using addTag function. This will be useful to group multiple requests with a string. This allows you to operate on all tasks with a particular tag. You can also cancel all the tasks with a single tag using WorkManager.cancelAllWorkByTag(String) .
4. Observe workmanager status
To understand this you should know how LiveData works in android. WorkManager provides a function getWorkInfoByIdLiveData() with return type as Livedata<WorkInfo>, so by observing this livedata, we get worker info which contains the status of the request and much more.
Alternatively, you can also observe the status of the worker using tags.
WorkManager with RxJava2
Workmanager supports reactive programming out of the box. All you need to do is import following line to your build.grade() file.
api"android.arch.work:work-rxjava2:2.1.0"
Now instead of extending the class with Worker extend it with RxWorker and override createWork() instead of doWork() to return a Single<Result> indicating the Result of your execution, as follows:
It’s just a basic Rxworker with a single operation. Whereas in real-time you might want to do multiple operations, some might be service calls, saving data in local DB or data computations. Let’s see how we can do that
WorkManager with Kotlin Coroutines
Workmanager supports Kotlin Coroutines out of the box. All you need to do is import following line to your build.grade() file.
Now instead of extending the class with Worker extend it with CoroutineWorker and override doWork(). Observe that doWork is a suspend functions here and if necessary we can override coroutineContext variable and assign a context to it.
Real-time work with workmanager
Now we know how to use workmanager with Rxjava2 and Kotlin coroutines, let’s see how we can use this knowledge to solve real time problems.
Let’s consider very common problem that any app with a backend server will face i.e sync data from local DB to remote server .
Here we have a TV show tracking app with offline support. That means this app can work without internet if it loads the data from its servers at least once in its life time. So consider a situation where the user is in offline mode and he has marked some of the episodes as watched, in this situation we save the changes in local DB and wait for internet connection. But what if user closed the app, phone got restarted or any other 100 things might happen.
This will be the perfect situation where Periodic Work Request comes in handy. Let’s say that a periodic work request is triggered when user first logged-in. This work request sync local DB data to its remote servers in every 12hours. Let’s see how we can start a workmanager
Requirements: Need internet connection, phone battery charge shouldn’t be less and should trigger for every 12hours interval.
Above code make sure that a worker will trigger every 12 hours with specified conditions. No lets see how we do things in that worker
Here first we need to get data from local DB, lets say we use room database for local DB. Below code shows how to get data from Room database.
After that we should filter which shows need to be updated.
Now we need to update these shows to remote server.
Now its time to put the pieces together
Useful links:
If you want to learn more or still have any doubts
Watch this video
Read official documentation
If you want to integrate Dagger with Workmanager read this article
Feel free to comment if there any suggestions or improvements.