Android Work Manager Basics

Android Work Manager Basics

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 the Result 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 Success
  • Result.failure() - Work failed
  • Result.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

image.png

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

Please provide feedback