Periodic WorkManager and Kotlin Coroutines
WorkManager is an Android Jetpack library that makes it easy to schedule deferrable, asynchronous tasks that must be run reliably. It is the best practice for most background work on Android.
Oops!! I understand that the definition may be a bit difficult to understand so let’s take an example:
Example
Let’s say you have a task to upload log files to the server
There are few tasks that you need to perform:
1. Create Log files
2. Write data to the Log files
3. Compress the size of file and then upload it to server
In each tasks there is a constraint that needs to be checked — that there is sufficient battery when you are creating or writing to Log files, that you have enough storage space when compressing the file and that you have a good network connection when uploading the files
This is an example of a task that is:
1. Deferrable (capable of being postponed), because you don’t need it to happen immediately, and in fact you might want to wait for some constraints to be met (such as waiting for a network connection and good battery strength).
2. Needs to be guaranteed to run, regardless of if the app exits or device restarts, because you might need the log files for some important processing of data
Okay so now we have understood what is WorkManager, In this blog post, I’ll cover :
- WorkManager in Kotlin
- Defining periodic work
WorkManager in Kotlin
For using WorkManager in Kotlin we will be using KTX library (KoTlin eXtensions). The KTX version of WorkManager provides extension functions for more concise and idiomatic Kotlin.
You can use the KTX version of WorkManager by adding a dependency to the build.gradle as follows:
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
This Library also includes CoroutineWorker
and other helpful extension functions for WorkManager.
CoroutineWorker
Similar to the Worker class, In kotlin we have a CoroutineWorker which differs from the Worker class is that the doWork() method in a CoroutineWorker is a suspend function and can run asynchronous tasks, while Worker’s doWork() can only execute synchronous tasks
By default, this runs on Dispatchers.Default . Another important thing to note is that CoroutineWorker
handle stoppages automatically by cancelling the coroutine. You don't need to do anything special to handle work stoppages.
Defining Periodic Work
There are two types of WorkRequest:
OneTimeWorkRequest:
AWorkRequest
that will only execute once.PeriodicWorkRequest:
AWorkRequest
that will repeat on a cycle.
We will be using PeriodicWorkRequest
for our repetitive periodic task
Suppose we have to execute a work daily for example sync data from server at a specified time say 7:00 am in the morning. You can specify a 24 hours period, but because the work is executed respecting Android’s battery optimization strategies, you can only expect your Worker to be executed around that time. You can then have an execution at 7:00 am the first day, 7:25 am the second day and so on.
If you need to execute a worker at roughly the same time, every day, you can use a PeriodicWorkRequest with an initial delay so that you execute it at the right time
It is very important to remember that the exact time that the worker is going to be executed depends on the constraints that you’re using in your work request and on the optimizations done by the Android platforms.
The conflict resolution policy used as a second parameter in enqueueUniquePeriodicWork() specifies what WorkManager should do if there’s already an unfinished chain of work with that unique name:
- Cancel the existing chain and
REPLACE
it with the new one. KEEP
the existing sequence and ignore your new request.
Note : If your work manager is not executing even once then you might need to disable battery optimization due to Chinese OEMs optimisations.
Go to settings ->Battery -> Battery Optimisation -> Select your app -> Select Don’t Optimize
You can also put it in your code for Battery Optimisation checks
Conclusion
This article outlines how to create a periodic request to perform background tasks with the Work Manager in your android application.
You can refer to my github repo for the whole code. Also don’t forget to clap if you like the post ;)