Schedule Task with WorkManager | Kotlin

Ali Talha Çoban
4 min readFeb 4, 2022

In applications on the phone, some operations take place when the application is open, while others continue to perform some operations even when closed. This running operations when the app is closed can be managed by WorkManager. In this article I’ll talk about Android WorkManager and show you how to use it in your apps.

What is Android WorkManager ?

Android WorkManager is a background processing library which is used to execute background tasks which should run in a guaranteed way but not necessarily immediately such as deferrable, asynchronous tasks etc.

Android WorkManager is a part of Android Jetpack and is one of the Android Architecture Components. WorkManager is the recommended solution for persistent work. So, what is the persistent work ? Persistent work is work done when the application restarts and remains scheduled when the system restarts. Because most background processing is best accomplished through persistent work, WorkManager is the primary recommended API for background processing. You should use WorkManager for all forms of persistent work.

Now that we know what Android WorkManager is in general, we can move on to coding. I will show you other things you need to know about WorkManager on coding.

Implementation

To Integrate work manager in your project

dependencies {
def work_version = "2.7.1"

// (Java only)
implementation "androidx.work:work-runtime:$work_version"

// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"

// optional - RxJava2 support
implementation "androidx.work:work-rxjava2:$work_version"

// optional - GCMNetworkManager support
implementation "androidx.work:work-gcm:$work_version"

}

Define a work

Work is defined using the Worker class. The doWork() method runs asynchronously on a background thread provided by WorkManager. To create some work for WorkManager to run, extend the Worker class and override the doWork() method. Our aim in our project is to increase the number we will assign each time the application is opened.

I create Worker class named Refreshing ( you can define the name of Worker class whatever you want )

To see the number we assigned, open Logcat and type System.out there .

Because we keep small data, I used sharedPreferences to keep data on the phone and create a function named refreshData() . We’ll increase the number with this function. Result returns the status of the work done in doWork() method. There are 3 types of Result which are;

  • Result.success()→ The work finished successfully.
  • Result.failure() → The work failed.
  • Result.retry() → The work failed and should be tried at another time according to its retry policy.

We need to create a WorkRequest in MainActivity.kt which defines how and when work should be run. It has two types;

  • OneTimeWorkRequest → Runs the task only once
  • PeriodicWorkTimeRequest → Runs the task after a certain time interval.

Before create a WorkRequest, create a data we’ll use in MainActivity.kt

val data = Data.Builder().putInt("iKey",1).build()

Then,

val workRequest : WorkRequest = OneTimeWorkRequestBuilder<Refreshing>()
.setInputData(data)
.build()

We need to submit the WorkRequest to the system

WorkManager.getInstance(this).enqueue(workRequest)

Constrains

We can add specific constraints in our WorkRequest to customize it meaining we can check some situtations of the device such as internet connection, charching status, idle time, device storage etc. (You can add any properties you want, we don’t need to them for this project)

val constraint = Constraints.Builder()
//.setRequiresDeviceIdle(true)
//.setRequiresCharging(true)
//.setRequiredNetworkType(NetworkType.CONNECTED)
//.setRequiresBatteryNotLow(true)
//.setRequiresStorageNotLow(true)
.build()

And add the constrains to the WorkRequest

val workRequest : WorkRequest = OneTimeWorkRequestBuilder<Refreshing>()
.setConstraints(constraint)
.setInputData(data)
.build()

Our project is ready. Now, we can run the project and closed the app and open again. If the number increases by one for every open-close, it means there is no problem.

Control status

You don’t need to do this step but if you want to check the status of the WorkManager after your task runs, you can use the WorkInfo object.

WorkManager.getInstance(this).getWorkInfoByIdLiveData(workRequest.id).observe(this
) {
if (it.state == WorkInfo.State.RUNNING) {
print("RUNNING")
} else if (it.state == WorkInfo.State.CANCELLED) {
print("CANCELLED")

} else if (it.state == WorkInfo.State.FAILED) {
print("FAILED")

} else if (it.state == WorkInfo.State.SUCCEEDED) {
print("SUCCEEDED")

}
}

Cancel Work

You can cancel the work in the queue

WorkManager.cancelWorkById(workRequest.id)

Here is the whole MainActivity

Contact ;

--

--