What is a WorkManager in Android? When to use it?
July 4, 2024
WorkManager OverView in Android
WorkManager is an Android Jetpack library that provides a powerful and flexible way to schedule and execute background tasks. It ensures that your tasks run reliably, even if the app is closed or the device restarts.
Key Features:
Guaranteed Execution: WorkManager guarantees that your tasks will eventually run, even if the app is closed, the device restarts or the user navigates away from the app.
Constraints: You can define constraints for your tasks, such as network availability, battery level, or storage space. WorkManager will only execute the task when the constraints are met.
Chaining and Parallelism: You can chain tasks together to create complex workflows and run tasks in parallel to improve efficiency.
One-Time and Periodic Tasks: WorkManager supports one-time tasks that run once and periodic tasks that repeat at intervals.
Backward Compatibility: WorkManager provides a consistent API across different Android versions, handling compatibility issues for you.
When to Use WorkManager:
Use WorkManager for tasks that:
Need guaranteed execution: Tasks that must be completed even if the app is closed or the device restarts (e.g., uploading data to a server, syncing data in the background).
Have constraints: Tasks that should only run under specific conditions (e.g., downloading a large file only when connected to Wi-Fi).
Can be deferred: Tasks that don’t need to be executed immediately and can be scheduled for a later time (e.g., sending notifications at a specific time).
Involve complex workflows: Tasks that require multiple steps or dependencies (e.g., processing images and then uploading them).
When Not to Use WorkManager:
Don’t use WorkManager for tasks that:
Require immediate execution: Tasks that need to be performed instantly (e.g., responding to user input).
Are short-lived: Tasks that are completed quickly and don’t need the guarantees provided by WorkManager.
A Sample Coding Demonstration of WorkManager
MainActivity.kt
package com.codingstudio.workmanagerdemo
import android.content.Context
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.work.*
import java.util.concurrent.TimeUnit
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Simple Work Request
val simpleWorkRequest = OneTimeWorkRequestBuilder<SimpleWorker>()
.build()
// Work Request with Constraints
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.setRequiresStorageNotLow(true)
.apply {
setRequiresDeviceIdle(true)
}
.build()
val constrainedWorkRequest = OneTimeWorkRequestBuilder<ConstrainedWorker>()
.setConstraints(constraints)
.build()
// Periodic Work Request
val periodicWorkRequest = PeriodicWorkRequestBuilder<PeriodicWorker>(
15, TimeUnit.MINUTES
).build()
// Chaining Work Requests
val workManager = WorkManager.getInstance(applicationContext)
workManager.enqueue(simpleWorkRequest)
workManager.enqueue(constrainedWorkRequest)
workManager.enqueue(periodicWorkRequest)
}
}
class SimpleWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
Log.d("SimpleWorker", "Simple work executed")
return Result.success()
}
}
class PeriodicWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
Log.d("PeriodicWorker", "Periodic work executed")
return Result.success()
}
}
class ConstrainedWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
Log.d("ConstrainedWorker", "Constrained work executed")
return Result.success()
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
>
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
Explanation:
Simple Work Request: A basic OneTimeWorkRequest is created for SimpleWorker.
Work Request with Constraints:
Constraints are defined for network, charging, battery, storage, and device idle state.
A OneTimeWorkRequest is created for ConstrainedWorker with these constraints.
Periodic Work Request: A PeriodicWorkRequest is created for PeriodicWorker to run every 15 minutes.
Chaining Work Requests:
WorkManager is used to enqueue all the work requests.
Work requests are chained using beginWith, then, and enqueue to execute in sequence.
Workers:
SimpleWorker, ConstrainedWorker, and PeriodicWorker are simple worker classes that log a message when their work is executed.
Thank you...