当前位置:网站首页>Learning II of workmanager

Learning II of workmanager

2022-07-05 10:16:00 Mr_ Tony

One 、 Preface

Work There are several states during operation . At run time , State It also changes . When the task begins , Status is ENQUEUED. Run time transition to RUNNING, At the end of the run, it will become SUCCEEDEDFAILED. If you try again , The state will return to ENQUEUED. If you cancel the work , The state will become CANCELLED.

SUCCEEDEDFAILED and CANCELLED All indicate the termination status of this work . If your work is in any of the above states ,WorkInfo.State.isFinished() Will return to true.

The following is the flow chart of task execution

 Insert picture description here

The above is a one-time task execution process . If it's a timed mission , Then there won't be SUCCEEDEDFAILED state . The following is the flow chart of scheduled tasks .

 Insert picture description here

Two 、 Only job

Generally speaking, the following methods can be used to start work

      WorkManager
            .getInstance(this)
            .enqueue(uploadWorkRequest)

But if we inadvertently write the code twice , Then the task will be performed twice ( Although this should not appear ). To avoid this problem , Officials provide the only way to ensure the execution of one-time tasks and scheduled tasks respectively .

Both methods accept 3 Parameters :

  • uniqueWorkName - Used to uniquely identify a work request String.
  • existingWorkPolicy - this enum You can tell WorkManager: If there is a unique work chain with that name that has not yet been completed , What should be done . For details , see also Conflict resolution policy .
  • work - To schedule WorkRequest.

The reference codes are as follows :


val sendLogsWorkRequest =
       PeriodicWorkRequestBuilder<SendLogsWorker>(24, TimeUnit.HOURS)
           .setConstraints(Constraints.Builder()
               .setRequiresCharging(true)
               .build()
            )
           .build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
           "sendLogs",
           ExistingPeriodicWorkPolicy.KEEP,
           sendLogsWorkRequest
)

3、 ... and 、 Conflict strategy

Please refer to the official website below

When scheduling only work , You must inform WorkManager A conflict occurs when an operation is to be performed . You can do this by passing an enumeration when you add work to the queue .

For one-time work , You need to provide a ExistingWorkPolicy, It supports... For handling conflicts 4 An option .

  • REPLACE: Replace an existing job with a new one . This option will cancel the existing work .
  • KEEP: Keep your current job , And ignore new jobs .
  • APPEND: Attach new work to the end of existing work . This policy will lead to your new job link To existing work , After the existing work is completed .

Existing jobs will be a prerequisite for new jobs . If the current job becomes CANCELLED or FAILED state , New jobs will also become CANCELLED or FAILED. If you want to run a new job regardless of the state of your existing job , Please switch to APPEND_OR_REPLACE.

  • APPEND_OR_REPLACE The function is similar to APPEND, But it doesn't depend on precondition Working state . Even if the existing work becomes CANCELLED or FAILED state , The new job will still work .

For regular work , You need to provide a ExistingPeriodicWorkPolicy, It supports REPLACE and KEEP These two options . The functions of these options correspond to ExistingWorkPolicy Function the same .

Four 、 Observe the state of work

When the work starts , The corresponding work information can be obtained in the following ways .


// by id
workManager.getWorkInfoById(syncWorker.id) // ListenableFuture<WorkInfo>

// by name
workManager.getWorkInfosForUniqueWork("sync") // ListenableFuture<List<WorkInfo>>

// by tag
workManager.getWorkInfosByTag("syncTag") // ListenableFuture<List<WorkInfo>>

The assignment methods corresponding to the above three acquisition methods are as follows :

// by id
val uploadWorkRequest: OneTimeWorkRequest = OneTimeWorkRequest.from(WorkTest::class.java)// Simple way 
val workerId = uploadWorkRequest.id

//by name
 WorkManager
            .getInstance(this)
            .enqueueUniqueWork("workName",
                ExistingWorkPolicy.KEEP,
                uploadWorkRequest)

//by tag
 val uploadWorkRequest: WorkRequest = // Complex builder approach 
          OneTimeWorkRequestBuilder<WorkTest>()
                .addTag("first")
                .build()

The query returns WorkInfo Object's ListenableFuture, This value contains the of the work id、 Its mark 、 Its current State And by Result.success(outputData) Any output data set .

Using each method LiveData variant , You can observe by registering listeners WorkInfo The change of ( It should be noted that the name of the called function is getWorkInfoByIdLiveData instead of getWorkInfoById()). for example , If you want to display a message to the user after a job is successfully completed , You can make the following settings :

workManager.getWorkInfoByIdLiveData(syncWorker.id)
               .observe(viewLifecycleOwner) {
      workInfo ->
   if(workInfo?.state == WorkInfo.State.SUCCEEDED) {
     
       Snackbar.make(requireView(),
      R.string.work_completed, Snackbar.LENGTH_SHORT)
           .show()
   }
}

5、 ... and 、 Complex query

WorkManager 2.4.0 And later versions support the use of WorkQuery Object to perform complex queries on the jobs that have been queued .WorkQuery Supports tags by work 、 A combination of status and unique work name .

The following example shows how to find a with “syncTag” Mark 、 be in FAILED or CANCELLED state , And the unique job name is “preProcess” or “sync” All work of .

val workQuery = WorkQuery.Builder
       .fromTags(listOf("syncTag"))
       .addStates(listOf(WorkInfo.State.FAILED, WorkInfo.State.CANCELLED))
       .addUniqueWorkNames(listOf("preProcess", "sync"))
   .build()

val workInfos: ListenableFuture<List<WorkInfo>> = workManager.getWorkInfos(workQuery)

WorkQuery Every component in ( Mark 、 Status or name ) And other components are AND logical relationship . Every value in the component is OR logical relationship . for example :(name1 OR name2 OR ...) AND (tag1 OR tag2 OR ...) AND (state1 OR state2 OR ...).

WorkQuery It also applies to equivalent LiveData Method getWorkInfosLiveData().

6、 ... and 、 Cancel and stop work

Sometimes tasks need to be cancelled , You can use the following


// by id
workManager.cancelWorkById(syncWorker.id)

// by name
workManager.cancelUniqueWork("sync")

// by tag
workManager.cancelAllWorkByTag("syncTag")

WorkManager Will check the work in the background State. If the work has complete , The system doesn't do anything . otherwise , The status of the work will change to CANCELLED, Then it won't run . whatever Rely on this work Of WorkRequest The assignment will also become CANCELLED.

at present ,RUNNING May receive a reply to ListenableWorker.onStopped() Call to . If any cleaning operation is required , Please replace this method . For details , see also Stop the running worker .

So after the task stops , Can be rewritten in onStopped() Function to handle the closing work . It can also be done through ListenableWorker.isStopped() Come and see if the task of wiping sweat stops , Examples are as follows :

class WorkTest(val appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams) {
    
    override fun doWork(): Result {
    
        if(isStopped){
    
            return Result.success()
        }
        return Result.success()
    }
}

7、 ... and 、 Reference link

  1. Management work  |  Android developer  |  Android Developers
原网站

版权声明
本文为[Mr_ Tony]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050949393608.html