WorkManager in Android

Odhiambo BrandyOdhiambo Brandy
6 min read

Introduction

WorkManager is an Android library that makes it simple to plan and carry out deferrable, asynchronous tasks that must continue to run even if the app is closed or the device is restarted.

WorkManager is a powerful tool for scheduling and executing tasks in Android, and it can be used for a wide range of tasks such as uploading data to a server, fetching data from a server, or performing periodic maintenance.

WorkManager is a part of Android Jetpack, a set of libraries, tools, and guidance to help you build great Android apps. It is designed to be backward-compatible and to work with the AndroidX library.

Background work

Background work refers to operations that are done, without requiring user interaction or input. These tasks are often used to perform deferred, non-urgent work that can be safely run at a later time, even if the app is closed or the device is restarted.

Examples of background work that can be performed with WorkManager include uploading data to a server, fetching data from a server, or performing periodic maintenance.

A background task can be Persistent or Asynchronous

Persistent Work

  • Persistent work is a form of background task that must be completed even if the device is rebooted or the app is closed. Even if the device is not in use at the time or the app has been removed and reinstalled, persistent work might be helpful for tasks that need to be finished.

Type of Persistent work

1.Main persistent work

  • Immediate - This is a one-time work that begin immediatly and complete soon.
  • Long Running - This is a periodic work that runs for longer time than 10 minutes.
  • Deferrable - This is a periodic work that starts at a later time and can run periodically.

2.Periodic Work

This kind of work is done on a regular basis, such once an hour or once a day. You can utilize periodic work to carry out routine operations like obtaining data from a server or deleting outdated data.

3.One-Time Work

This kind of work is completed only once and is never done again. One-time work can be used to carry out operations that must only be carried out once, such as downloading or uploading data to a server.

4.Exisiting Work

This kind of work is used to retrieve and execute already-enqueued work that hasn't yet been carried out. Existing work can be used to cancel unnecessary work or to verify the status of work that has been queued.

5.Chained Work

Using this kind of work, you can chain together several workers so that you can run one after the other has finished. Chained work is a method for building intricate workflows with a number of jobs that must be completed in a specific order.

6.Unique Work

This kind of work is used to make sure that there is never more than one instance of a specific worker active at once. To prevent several instances of the same task from being executed simultaneously, utilize unique work.

Asynchronous Work

  • Asynchronous work is a type of background task that is performed asynchronously, meaning that it is executed on a separate thread from the main thread and does not block the main thread. Asynchronous work is useful for tasks that may take a long time to complete, such as tasks that involve network communication or data processing.

Features of WorkManager

With WorkManager, you can specify the conditions under which your tasks should run (such as when the device is connected to a particular network or when the battery is charged above a certain level), and the library will take care of running the tasks when the conditions are met.

  • Work Constraints

    These are conditions that determines when a task should be run. You can specify constraints when enqueuing a task with WorkManager, and the task will only be run when the specified constraints are met.The constraints can be set like this

     val constraints = Constraints.Builder()
          .setRequiredNetworkType(NetworkType.CONNECTED)
          .setRequiresBatteryNotLow(true)
          .build()
    
      val workRequest = OneTimeWorkRequest.Builder(MyWorker::class.java)
          .setConstraints(constraints)
          .build()
    
      WorkManager.getInstance().enqueue(workRequest)
    
  • Robust scheduling

    Robust scheduling is a feature of WorkManager that ensures that tasks are executed even if the device is restarted or the app is closed.

    val workRequest = PeriodicWorkRequest.Builder(MyWorker::class.java, 15, TimeUnit.MINUTES)
        .setInitialDelay(1, TimeUnit.HOURS)
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.MINUTES)
        .build()

    WorkManager.getInstance().enqueue(workRequest)
  • Expendited work

    Refers to tasks that need to be completed quickly and with a greater priority. Those that must be finished fast, such as those required to offer a flawless user experience or tasks that must be performed on a strict deadline, can benefit from the utilization of expended effort.

val workRequest = OneTimeWorkRequest.Builder(MyWorker::class.java)
        .addTag("expended_work")
        .build()

WorkManager.getInstance().beginUniqueWork("unique_work_name", ExistingWorkPolicy.REPLACE, workRequest).enqueue()
  • Retry policy

    These are set of policies that outline how WorkManager ought to respond to jobs that do not run or finish correctly. The number of times and the interval between retries that WorkManager should do on a failed job can both be specified by retry policies.

    val workRequest = OneTimeWorkRequest.Builder(MyWorker::class.java)
          .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.MINUTES)
          .build()
    
      WorkManager.getInstance().enqueue(workRequest)
    
  • Work chaining

    Refers to the ability to chain multiple workers together, so that one worker is run after another worker has completed. This allows you to create complex workflows that involve multiple tasks that need to be run in a particular order.

      val work1 = OneTimeWorkRequest.Builder(Worker1::class.java).build()
      val work2 = OneTimeWorkRequest.Builder(Worker2::class.java).build()
      val work3 = OneTimeWorkRequest.Builder(Worker3::class.java).build()
    
    WorkManager.getInstance().beginWith(work1)
          .then(work2)
          .then(work3)
          .enqueue()
    

Relationship of WorkManager with other APIs

1.Kotlin Coroutines

Kotlin Coroutines are a lightweight concurrency library that allows you to write asynchronous code in a more sequential and easy-to-read style. You can use Kotlin Coroutines to write asynchronous code that performs tasks such as network requests or database queries, and then use WorkManager to schedule and execute the coroutines in the background.

To use WorkManager and Kotlin Coroutines together, you'll need to use a CoroutineWorker class, which is a special type of Worker that is designed to work with Kotlin Coroutines. You can then use the with context () function to run your coroutines in the background, and the await() function to wait for the results.

Example:

class MyWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        // Run a coroutine in the background
        val result = withContext(Dispatchers.IO) {
            // Perform some asynchronous work
            val response = api.fetchData()
            // Return the result
            response.body
        }

        // Return the result
        return Result.success(result)
    }
}

Alarm Manager

WorkManager and AlarmManager are both Android classes that can be used to schedule and execute tasks in the background. However, they have some key differences that make them suitable for different use cases.

AlarmManager, on the other hand, is a more basic class that is primarily designed to schedule tasks that need to be run at a specific time or at regular intervals. AlarmManager is not as flexible as WorkManager, and it does not have features such as robust scheduling or work chaining. However, AlarmManager is simpler to use and can be a good choice for tasks that are relatively straightforward and don't require the advanced features of WorkManager.

To get the WorkManagerCode vist this Github Repo

Conclusion

In conclusion, WorkManager is a strong Android class that gives you the flexibility and reliability to schedule and carry out a variety of background tasks. WorkManager is ideal for tasks that must be executed on a regular basis, jobs that must continue to run even when the device is restarted, and tasks that must be linked together to create intricate workflows. WorkManager is a great option for jobs that need to execute in reaction to changes in the device's connectivity or battery level because it contains features like comprehensive scheduling and support for a range of triggers. For any Android developer that wants to run background processes in their app, WorkManager is a crucial tool.

1
Subscribe to my newsletter

Read articles from Odhiambo Brandy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Odhiambo Brandy
Odhiambo Brandy

Android developer Java|Kotlin | WTM