Work Manager for your background task

Ikhwan Koto
4 min readAug 1, 2019

--

Hello everyone

Welcome to my first article. This is my first time writing an article since the lecture. I wrote as a note for me, share knowledge, and various things.

If you want to read this post in Bahasa, you can open this link: https://www.yukngoding.id/2020/02/01/work-manager-untuk-background-task/

If there is a mistake in my writing please commented on the bottom, thank you.

Okay, for this time I will discuss about Work Manager. What is that? And why do you have to try it?

Work manager is one of many topic at Android Jetpack. With it, you can schedule deferrable, asynchronous tasks that are expected to run even if the app exits or device restarts. There are several key features about the work manager.

  • Add work constraints like network availability or charging status
  • Schedule asynchronous one-off or periodic tasks
  • Monitor and manage scheduled tasks
  • Chain tasks together
  • Ensures task execution, even if the app or device restarts
  • Adheres to power-saving features like Doze mode

Lets start to make the code

First, Open the build.gradle file for your project and add the google() repository as shown below:

allprojects {
repositories {
google()
jcenter()
}
}

Don’t forget the depedencies.

dependencies {
implementation "android.arch.work:work-runtime:1.0.0"
}

Sync your project, and let’s make the Worker class. It serves to run the code in backgorund. In this article, I will make news worker to synchronize my news data.

import android.content.Context
import android.os.StrictMode
import androidx.work.ListenableWorker
import androidx.work.Worker
import androidx.work.WorkerParameters
class NewsWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) { override fun doWork(): Result {
if(snycNewsData())
return ListenableWorker.Result.success()
else
return ListenableWorker.Result.failure()
}
fun snycNewsData(): Boolean {

//Sync News Data

return true
}
}

Let see the code. The main point of Worker class is doWork function. What do you want to do in the background, your business logic, put it all in this function. You should know the function of it took the response value. If the code are running smoothly, you could set the response value with ListenableWorker.Result.success() and if fails you could set the response values with ListenableWorker.Result.failure().

Now, lest call the Worker class from the activity.

var mWorkManager = WorkManager.getInstance()
mWorkManager.beginUniqueWork(
"UniqueWork", ExistingWorkPolicy.REPLACE,
OneTimeWorkRequest.from(NewsWorker::class.java)).enqueue()
}

Let see the code again. With the code, we will start a unique worker. The function of “UniqueWork” is for identity the worker. If there are other workers with the same unique work name(in this case is UniqueWork), the other worker will be replaced with the new one. This happened because ExistingWorkPolicy.REPLACE.

Okay, until this part you have made a simple task with WorkManager. Congrats..

Lets make another task with different case. Assume that, you want to do a multiple task in sequence. We have done one worker class. Lets make another one.

import android.content.Context
import android.os.StrictMode
import androidx.work.ListenableWorker
import androidx.work.Worker
import androidx.work.WorkerParameters
class ProfileWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {override fun doWork(): Result {
if(snycProfile())
return ListenableWorker.Result.success()
else
return ListenableWorker.Result.failure()
}
fun snycProfile(): Boolean {

//Sync News Data

return true
}
}

Now we have 2 worker. We want to execute Profile Worker, and when it is done, we want to continue with News Worker. Let’s make the code.

var mWorkManager = WorkManager.getInstance()
var workContinue = mWorkManager.beginUniqueWork(
"ContinueWorker",
ExistingWorkPolicy.REPLACE,
OneTimeWorkRequest.from(ProfileWorker::class.java)
)

workContinue = workContinue.then(
OneTimeWorkRequest.from(NewsWorker::class.java))
workContinue.enqueue()

use then for add another task in your continue task.

Congratulation, you have made a Continue Task with Work Manager.

Now, imagine we want run a task with a network requirement. So when the network available, the task will run. Lets add extra code for this condition.

var mWorkManager = WorkManager.getInstance()
mWorkManager.beginUniqueWork(
NewsWorker.CONST_OUTPUT,
ExistingWorkPolicy.REPLACE,
OneTimeWorkRequest.Builder(NewsWorker::class.java)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED).build()).build()
).enqueue()

Okay, you have made a task with connection requirement with Work Manager.

For the last, i will explain periodic task with work manager. Assume we want to run News Worker every 20 minutes. Lets make the code.

var mWorkManager = WorkManager.getInstance()
val periodicWork = PeriodicWorkRequest.Builder(
NewsWorker::class.java, 20, TimeUnit.MINUTES)
.build()
mWorkManager.enqueue(periodicWork)

Congratulation. You have made many background task with WorkManager.

But before I finish this article, I have a note, especially for periodic task with work manager.

First, assume that you have a periodic task with 20 Minutes interval. You start a periodic task at 9:00 a.m. The next task will be run at 9:20 a.m., right? The answer is MAYBE. For some reason the next task will be accurate, and sometimes not. But it still in the correct interval. So let say the first task run in correct interval at 9:20 a.m. The next one, run in the uncorrect interval at 9:44 a.m. And the next one, the task run in the correct interval again, at 10:00 AM.

Second, the periodic task can run in a good performance, if you set the time for more than 15 Minutes. If you make it below that time, it will run in poor performance.

Thanks for your time. Btw, I uploaded a sample project in my GitHub, just visit it.

Byeeee,, Thanks again.. :D

--

--