Android development, use kotlin to learn WorkManager

Introduction to WorkManager


Google launched the WorkManager component. WorkManager is very suitable for processing some tasks that require regular execution. It can automatically select whether the underlying layer is implemented by AlarmManager or JobScheduler according to the version of the operating system, thereby reducing our cost of use. In addition, it also supports periodic tasks, chain task processing and other functions, and is a very powerful tool.

Basic usage of WorkManager


Add dependencies to the app/build.gradle file

 implementation "androidx.work:work-runtime:2.7.1"

The basic usage of WorkManager is actually very simple, mainly divided into the following 3 steps:

  • Define a background task and implement specific task logic.
  • Configure the running conditions and constraint information of the background task, and construct a background task request.
  • Pass the background task request into the enqueue() method of WorkManager, and the system will run at the appropriate time.

The first step is to define a background task, here create a SimpleWorker class, the code is as follows:

class SimpleWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): Result {
        Log.d("SimpleWorker", "do work in SimpleWorker")
        return Result.success()
    }

}

The second step is to configure the running conditions and constraint information of the background task. The code is as follows:


 //设置约束条件
 //NetworkType.CONNECTED 最通用的连上网络
 //NetworkType.UNMETERED  WF
 //NetworkType.METERED 流量,4G
  val constraints: Constraints =Constraints.Builder()
       .setRequiredNetworkType(NetworkType.CONNECTED)
       .build()
  val request=OneTimeWorkRequest.Builder(SimpleWorker::class.java)
        .setConstraints(constraints)
        .build()
            

 The last step is to pass the constructed background task request into the enqueue() method of WorkManager, and the system will run at an appropriate time. The code is as follows:

WorkManager.getInstance(context).enqueue(request)

Handle complex tasks with WorkManager


(1) Let the background task run after the specified delay time

val request=OneTimeWorkRequest.Builder(SimpleWorker::class.java)
                .setInitialDelay(5,TimeUnit.MINUTES)
                .build()

(2) Add tags to background task requests

val request=OneTimeWorkRequest.Builder(SimpleWorker::class.java)
                ...
                .addTag("simple")
                .build()

 (3) Cancel the background task request through the label

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

(4) Even if there is no label, the background task request can be canceled by id

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

(5) Cancel all background task requests at once

WorkManager.getInstance(this).cancelAllWork()

(6) If Result.retry() is returned in the doWork() method of the background task, then the task can be re-executed in combination with the setBackoffCriteria() method.

setBackoffCriteria(): The first parameter is used to specify how the next retry time should be delayed if the task fails to execute again. There are two optional values: 1. LINEAR, which means the next retry time is delay in a linear fashion. 2. EXPONENTIAL, which means that the next retry time is delayed exponentially. The second parameter and the third parameter are used to specify how long to re-execute the task, and the minimum time cannot be less than 10 seconds.

val request=OneTimeWorkRequest.Builder(SimpleWorker::class.java)
                ...
                .setBackoffCriteria(BackoffPolicy.LINEAR,10,TimeUnit.SECONDS)
                .build()

(7) What is the effect of returning Result.success() and Result.failure() in the doWork method? These two return values ​​are actually used to notify the running result of the task. We can use the following code to monitor the running result of the background task:

WorkManager.getInstance(this).getWorkInfoByIdLiveData(request.id).observer(this){workInfo->
    if(workInfo.state==WorkInfo.State.SUCCEEDED){
        Log.d("MainActivity","do work succeeded")
    }else if(workInfo.state==WorkInfo.State.FAILED){
         Log.d("MainActivity","do work failed")
    }
}

chain task


Suppose there are 3 independent background tasks defined here: synchronizing data, compressing data and uploading data. Now we want to achieve the function of synchronizing first, then compressing, and finally uploading, we can use chain tasks to achieve it.

val sync=...
val compress=...
val upload=...
WorkManager.getInstance(this)
   .beginWith(sync)
   .then(compress)
   .then(upload)
   .enqueue()

Guess you like

Origin blog.csdn.net/weixin_63357306/article/details/127195294