Work manager is a library which helps to schedule a deferrable task that will execute for sure when constraints are met.
Example:
- When you want to download a video in a background only when android phone is connected to Wi-Fi and battery is charging.
- Periodically syncing data between server and android phone.
This tutorial is on kotlin
We will learn the work manger basics by making the work manager to sumup the numbers from 1 to 10 with 2 secs delay for each addition
Add Dependency :
val work_version = "2.5.0"
implementation "androidx.work:work-runtime-ktx:$work_version"
The above dependency is used when we have to use kotlin + coroutines
There are other dependencies
// (Java only)
implementation("androidx.work:work-runtime:$work_version")
// optional - RxJava2 support
implementation("androidx.work:work-rxjava2:$work_version")
// optional - Test helpers
androidTestImplementation("androidx.work:work-testing:$work_version")
// optional - Multiprocess support
implementation "androidx.work:work-multiprocess:$work_version"
Worker Class
- Worker class performs work synchronously on a background thread provided by Work manager
- A worker class must finish the work in ten minutes and return the
Result
. If this worker time is expired , then system will signal the worker to stop .
class SimpleAddWorker(context: Context, workerParameters: WorkerParameters) :
Worker(context, workerParameters) {
override fun doWork(): Result {
// log the thread info
Log.d("SimpleAddWorker", "Thread : ${Thread.currentThread().name}")
var total: Int = 0
// for loop to add the numbers
for (it in 1..10) {
total += it
// sleep for 2000 millis
sleepForAddition()
Log.d("SimpleAddWorker", "adding : $total by adding $it")
}
// return is result based on the total
return if (total > 0) {
Log.d("SimpleAddWorker", "Success and total is $total")
Result.success()
} else {
Log.d("SimpleAddWorker", "Failure and total is $total")
Result.failure()
}
}
}
doWork()
method is called on a background thread - you are required to synchronously do your work and return theResult
from this method.- Once you return from this method, the Worker is considered to have finished what its doing and will be destroyed.
Result
returned from doWork
will indicate work status as follows
Result.success()
- Work SuccessResult.failure()
- Work failedResult.retry()
- Work failed and it will be retried based on the work manager retry policy.
WorkRequest and WorkManager
WorkRequest
tells how the worker should run and when it should run.- In this example , we have used
OneTimeWorkRequest
which is for non- repeating work
// initialise the work manager
private val workManager = WorkManager.getInstance(this)
override fun onCreate(savedInstanceState: Bundle?) {
....
binding.buttonAdd.setOnClickListener {
Log.d("SimpleAddWorker" , "Thread : ${Thread.currentThread().name}")
// call the work manager to begin the task by using the OneTimeWorkRequest
workManager.beginWith(
OneTimeWorkRequest.from(SimpleAddWorker::class.java)
).enqueue()
}
}
Lets understand the work manager deferrable conditions vs App standby bucket
So , in the demo app we have used the active standby bucket to run the work immediately.
Output :
D/SimpleAddWorker: Thread : main
D/SimpleAddWorker: Thread : pool-1-thread-1
D/SimpleAddWorker: adding : 1 by adding 1
D/SimpleAddWorker: adding : 3 by adding 2
D/SimpleAddWorker: adding : 6 by adding 3
D/SimpleAddWorker: adding : 10 by adding 4
D/SimpleAddWorker: adding : 15 by adding 5
D/SimpleAddWorker: adding : 21 by adding 6
D/SimpleAddWorker: adding : 28 by adding 7
D/SimpleAddWorker: adding : 36 by adding 8
D/SimpleAddWorker: adding : 45 by adding 9
D/SimpleAddWorker: adding : 55 by adding 10
D/SimpleAddWorker: Success and total is 55
The sample code for the above discussed can be found at https://github.com/vprabhu/SimpleWorkManager
In the next article , we will discuss about the chaining the work request