Work Manager in Android

Work Manager in Android

WorkManager is one of the Android Architecture Components and part of Android Jetpack.

WorkManager is for background work that’s deferrable and requires guaranteed execution:

  • Deferrable means that the work is not required to run immediately. For example, sending analytical data to the server or syncing the database in the background is work that can be deferred.
  • Guaranteed execution means that the task will run even if the app exits or the device restarts.

WorkManager is not intended for in-process background work that can safely be terminated if the app process goes away or for work that requires immediate execution.

The WorkManager API is a suitable and recommended replacement for all previous Android background scheduling APIs, including FirebaseJobDispatcherGcmNetworkManager, and Job Scheduler. WorkManager incorporates the features of its predecessors in a modern, consistent API that works back to API level 14 while also being conscious of battery life.

WorkManager internally uses JobScheduler, AlarmManager or Firebase JobDispatcher to schedule work.

WorkManager schedules all the work on a different thread and not on the main thread.

Features:

  • Work Constraints: You can set the conditions to execute the work only when specific conditions met. For example, run only when the device is Wi-Fi, when the device idle, or when it has sufficient storage space, etc
  • Scheduling: WorkManager allows you to schedule work to run one- time or repeatedly using flexible scheduling windows. Scheduled work is stored in an internally managed SQLite database and WorkManager takes care of ensuring that this work persists and is rescheduled across device reboots. In addition, WorkManager adheres to power-saving features and best practices like Doze mode, so you don’t have to worry about it.
  • Flexible Retry Policy: Sometimes work fails. WorkManager offers flexible retry policies.
  • Work Chaining: For complex related work, chain individual work tasks together using a fluent, natural, interface that allows you to control which pieces run sequentially and which run in parallel.

Main Work Manager Classes:

  • Worker: This is where you put the code for the actual work you want to perform in the background. You’ll extend this class and override the doWork() method.
  • WorkRequest: This represents a request to do some work. You’ll pass in your Worker as part of creating your WorkRequest. When making the WorkRequest you can also specify things like Constraints on when the Worker should run.
  • WorkManager: This class actually schedules your WorkRequest and makes it run. It schedules WorkRequests in a way that spreads out the load on system resources, while honoring the constraints you specify.

Types of Work Requests:

  • OneTimeWorkRequest: A WorkRequest that will only execute once.
  • PeriodicWorkRequest: A WorkRequest that will repeat on a cycle.

Sample Code:

app/build.gradle dependency
// WorkManager dependency
def work_version = "1.0.1"
implementation "android.arch.work:work-runtime-ktx:$work_version"

/**
 * Worker class for performing background tasks
 */
class SampleWork(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {

    override fun doWork(): Result {
    
    // Result.success() : The work completed successfully.
    // Result.retry() : The work failed and WorkManager should retry it again.
    // Result.failure() : The work failed and there is no need to retry.
    return Result.success()
    }
}

/**
 * Create work requests and setup constrants
 */
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)
            .build()
        val work = PeriodicWorkRequestBuilder(2, TimeUnit.HOURS)
 // Schedule to run the work every 2 hrs
            .setConstraints(constraints)
            .setInputData(builder)
            .build()

/**
 *  Schedule the work
 */
        val workManager = WorkManager.getInstance(applicationContext)
        workManager.enqueue(work)