“This is the 13th day of my participation in the First Challenge 2022. For details: First Challenge 2022”
A, the WorkManager
WorkManager is the recommended solution for persistent work. Work is persistent when the schedule is maintained through application restarts and system restarts. Since most background processing is best done through persistence work, WorkManager is the primary recommended API for background processing.
Periodic tasks registered with WorkManager do not necessarily execute on time. This is not a Bug, but rather the system may try to reduce power consumption by putting together several tasks that trigger events close to each other. This can significantly reduce the number of CPU awakenings, thus effectively increasing battery life.
Note: WorkManager and Seriver are not a concept, nor are they directly related. Seriver is one of the four components of the Android system. WorkManager is just a tool for processing scheduled tasks.
Some of these concepts are already in place last time, so let’s go ahead and start using Kotlin.
Basic usage of WorkManager
2.1 Adding a Dependency
Add the following dependencies to your app/build.gradle file:
dependencies {
def work_version = "2.7.1"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
}
Copy the code
2.2 use the WorkManager
2.2.1 Defining tasks
The definition task must inherit from the Worker class and call its constructor (unique). Override the doWork() method.
Note: The doWork() method runs asynchronously on a background thread provided by the WorkManager, so you can safely perform time-consuming operations here.
/** * Create time: 2022/1/27 * Function: Define a task (Kotlin) */
class KotlinTestWork(appContext: Context, workerParams: WorkerParameters):
Worker(appContext, workerParams) {
override fun doWork(a): Result {
// Perform time-consuming operations
doSmothing()
return Result.success()
}
private fun doSmothing(a) {
// This is just a simple print
Log.e("KotlinTestWork"."KotlinTestWork performing doWork")}}Copy the code
The Result returned from doWork() informs the WorkManager service whether the work was successful and whether the work should be retried in case of failure:
- Result.success() : success.
- Result.failure() : failure.
- Result.retry() : The work fails and can be re-executed using the setBackoffCriteria() method of workRequest.Builder.
2.2.2 Build task request
WorkRequest.Worker defines the unit of work, and WorkRequest (and its subclasses) defines how and when it should run. In the simplest case, you can use OneTimeWorkRequest.
// Build the task request
// Method 1: simple Work without additional configuration
val fromWorkRequest: WorkRequest = OneTimeWorkRequest.from(KotlinTestWork::class.java)
// Method 2: complex Work, which can be configured using the builder
val workRequest: WorkRequest =
OneTimeWorkRequestBuilder<KotlinTestWork>().build()
Copy the code
2.2.3 Submitting WorkRequest to the System
Finally, the WorkRequest built tasks are submitted to the WorkManager using the enqueue() method. The system will run at the right time.
binding.btnDowork.setOnClickListener {
// Submit WorkRequest to the system
WorkManager
.getInstance(this)
.enqueue(workRequest)
}
Copy the code
Advanced usage of WorkManager
3.1 the task
- Observe the task
- The value of
- The constraint
@RequiresApi(Build.VERSION_CODES.N)
fun complexWork(a){
// Constraints
// val constraints = Constraints.Builder().apply {
// setRequiresDeviceIdle(true)// Whether the device is idle when triggered
// setRequiresCharging(true
// setRequiredNetworkType(networktype.unmetered)// Indicates the network status
SetRequiresBatteryNotLow (true)// Specifies whether the device battery should not fall below the critical threshold
// setRequiresStorageNotLow(true)// Specifies whether the available storage of the device should not fall below the critical threshold
//// addContentUriTrigger(myUri,false)// Whether {@link WorkRequest} updates should be run when specifying content {@link android.net.Uri}
// }.build()
/ / value
val data = Data.Builder().apply {
putString("name"."Scc")
putInt("age".25)
}.build()
// Build task
complexWorkRequest =
OneTimeWorkRequestBuilder<KotlinTestWorkInfo>()
// Execute after 1 minute, of course you can specify the unit with this method (ms/s/min/hour/day)
.setInitialDelay(1, TimeUnit.SECONDS)
.addTag("complex")
// .setConstraints(constraints)
.setInputData(data)
.build()
binding.btnObserveWorkinfo.setOnClickListener {
Log.e("Work"."start")
val workManager = WorkManager.getInstance(this)
workManager.getWorkInfoByIdLiveData(complexWorkRequest.id)
.observe(this){
Log.e("Work"."State:"+it.state)
if(! it.outputData.getString("work").isNullOrBlank()){
var msg = it.outputData.getString("work") +":"+it.outputData.getInt("length".5)
Log.e("Work"."Data:"+msg)
}
}
workManager.enqueue(complexWorkRequest)
}
}
Copy the code
3.2 Canceling or Stopping a Task
- Cancel a task by Id
- Cancel the task by Tag
- Cancel all tasks
WorkManager.getInstance(this).cancelAllWorkByTag("complex")
WorkManager.getInstance(this).cancelWorkById(complexWorkRequest.id)
WorkManager.getInstance(this).cancelAllWork()
Copy the code
3.3 Chain tasks
Suppose we have three separate background tasks: get an image, compress an image, and upload an image. So if we want to do this, we can do it using chained tasks.
// chain call
WorkManager.getInstance(this)
// Run parallel
.beginWith(listOf(work1, work2, work3))
// Continue to invoke the compression task after performing the signature operation
.then(cache)
// The upload task is invoked after the compression task is executed
.then(upload)
// Add to the WorkManager queue
.enqueue()
Copy the code
- BeginWith: beginWith() means to begin a chained task.
- Then: Use the then() method to link any subsequent tasks.
This article is more about using Kotlin to practice WorkManager. For more concept descriptions and Java practices, check out # Jetpack WorkManager. .