Use of Android Jetpack WorkManager

Posted by mr02077 on Tue, 28 Dec 2021 08:26:52 +0100

The official website link uses WorkManager to schedule tasks | Android Developers | Android Developers
https://developer.android.google.cn/topic/libraries/architecture/workmanager

WorkManager is an API that allows you to easily schedule reliable asynchronous tasks that should run even after exiting the application or restarting the device.

WorkManager is suitable for work that needs to run reliably. Even if the user navigates away from the screen, exits the application or restarts the device, it will not affect the execution of work. For example:

  • Send log or analysis data to the backend service
  • Synchronize application data with the server regularly

In short, WorkManager is used to perform background tasks.

Advantages:

  • Use work constraints to clearly define the best conditions for the work to run. Working constraints include sufficient power, networking constraints (such as Wifi only), equipment idle, etc.
  • Flexible scheduling. You can execute a single or periodic task, add a tag to the task, and cancel the task.
  • Flexible retry strategy. If the task execution fails, you can choose to retry.
  • Work chain. For multiple tasks, you can agree on the sequential execution relationship of tasks.

Start using,

1. Add dependency

dependencies {
    def work_version = "2.5.0"
    
    // WorkManager
    implementation "androidx.work:work-runtime:$work_version"
}

2. Customize Worker

Customize a task, inherit the Worker, rewrite the doWork() method, and implement the specific background task logic in the doWork() method.

import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters

class MyWorker(context: Context, parameters: WorkerParameters) : Worker(context, parameters) {

    override fun doWork(): Result {
        //TODO("Not yet implemented")
        // do really work
        return Result.success()
    }
}

The results returned by doWork() are:

  • Result.success(): the work completed successfully.
  • Result.failure(): work failed.
  • Result.retry(): work failed. You can retry in other periods according to the configured retry policy.

3. Create a WorkRequest

Create a single run background task request using OneTimeWorkRequest,

var request = OneTimeWorkRequest.Builder(MyWorker::class.java).build()

You can add labels and other constraints,

var request = OneTimeWorkRequest
    .Builder(MyWorker::class.java)
    //Execute in 10 minutes
    .setInitialDelay(10, TimeUnit.MINUTES)
    // Set tag to tag_request to cancel the task according to the tag
    .addTag("tag_request")
    // Combined with result Retry() is used. If the task fails, execute the task again,
    //If the task fails to execute, it will be retried after 60 seconds. If it fails again, the time interval of the next retry will increase linearly (it can also be set to increase exponentially (BackoffPolicy.EXPONENTIAL)
    .setBackoffCriteria(BackoffPolicy.LINEAR, 60, TimeUnit.SECONDS)
    .build()

If setBackoffCriteria is set, you can listen to the task execution results according to the task id,

WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id)
            .observe(this){ workInfo ->
                if (workInfo.state == WorkInfo.State.SUCCEEDED) {

                } else if (workInfo.state == WorkInfo.State.FAILED) {

                }
            }

4. Submit the WorkRequest to the system

It is very simple, so it will be submitted to the system, and the system will execute it at the right time.

WorkManager.getInstance(this).enqueue(request)

5. Work chain

If there are multiple tasks, their sequential execution relationship can be constrained,

val request1 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request1").build()
val request2 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request2").build()
val request3 = OneTimeWorkRequest.Builder(MyWorker::class.java).addTag("request3").build()

WorkManager.getInstance(this)
                .beginWith(request1)
                .then(request2)
                .then(request3)
                .enqueue()

Execute request1, then request2, and then request3. If request1 fails, request2 and request3 will not be executed.

6. Cancel the task

Cancel a single task based on id

WorkManager.getInstance(this).cancelWorkById(request.id)

Cancel all tasks under this tag according to the tag

WorkManager.getInstance(this).cancelAllWorkByTag("tag_request")

Cancel all tasks

WorkManager.getInstance(this).cancelAllWork()

Topics: Android kotlin jetpack