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 CoroutineWorkerhandle 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: A WorkRequest that will only execute once.
  • PeriodicWorkRequest: A WorkRequest 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 ;)