Android Practice WorkManager with Kotlin API

  • 2021-12-12 09:35:13
  • OfStack

Directory WorkManager Foundation Start Worker to perform tasks But what if I want to do asynchronous operations?

WorkManager provides a series of API, which can plan asynchronous tasks more conveniently. Even after the application is shut down or the device is restarted, it is still necessary to ensure that the tasks that are executed immediately or postponed are processed normally. For Kotlin developers, WorkManager provides the best support for synergy. In this article, I will show you the basic operations related to synergy in WorkManager by practicing WorkManager codelab. Then let's get started!

WorkManager Fundamentals

When you need a task to keep running, even if the user switches to another interface or the user switches the application to the background, even when the device restarts, it still does not affect the task status, so it is highly recommended to use WorkManager. Similar application scenarios include:

Upload log or report data Save pictures while processing them with filters Synchronize local data periodically over the network

If your immediate task can end when the user leaves a scope, such as switching to another interface, we recommend that you use Kotlin syndication directly.

In this WorkManager codelab tutorial, we blur the images and store the processed data on disk. Let's look at what operations are needed in this process.

Add work-runtime-ktx dependencies:


//  Get the latest version number   https://developer.android.google.cn/jetpack/androidx/releases/work
def work_version = "2.5.0"
implementation "androidx.work:work-runtime-ktx:$work_version"

First, implement our own Worker class. Here we will implement the code that really needs to perform business in the background. You can extend the Worker class and override the doWork () method. Because this class is very important, we will introduce it in detail later. Here is its original implementation code.


/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

class BlurWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params) {

    override fun doWork(): Result {
        val resourceUri = inputData.getString(KEY_IMAGE_URI)

        return try {
            if (resourceUri.isNullOrEmpty()) {
                Timber.e("Invalid input uri")
                throw IllegalArgumentException("Invalid input uri")
            }

            val outputData = blurAndWriteImageToFile(resourceUri)
            Result.success(outputData)
        } catch (throwable: Throwable) {
            Timber.e(throwable, "Error applying blur")
            Result.failure()
        }
    }
 … 
}

Next, we create our work request. In this case, we want the whole operation to run only once, so we use OneTimeWorkRequest. Builder and pass in the Uri of the picture to be blurred as a parameter.

Kotlin Tip: To create input data, we can use the workDataOf function, which will help us create a data builder, populate key-value pairs, and then create data for us.


/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

val blurBuilder = OneTimeWorkRequestBuilder<BlurWorker>()
val data = workDataOf(KEY_IMAGE_URI to imageUri.toString())
blurBuilder.setInputData(data)

We use the WorkManager class to add the above work to the schedule queue and run it. We can provide the tasks that need to be performed and the constraints of these tasks.


/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

val workManager = WorkManager.getInstance(application)
val continuation = workManager.beginUniqueWork(blurBuilder.build())
//  Perform a task 
continuation.enqueue()

Start the task of Worker

When you use Worker, WorkManager automatically calls Worker. doWork () in a background thread. Result returned by doWork () tells WorkManager whether the service succeeded or if it failed whether a retry is required.

Worker. doWork () is a synchronous call--your background operations need to be executed in a blocking fashion, and all tasks need to be completed at the end of the entire doWork () function. If you call asynchronous API in doWork () and return the result, you may have problems with the execution of your callback function.

But what if I want to do asynchronous operations?

Let's make the above example operation a little more complicated, such as the Uri that I want to store all the obfuscated files in the database.

So I created:

1 simple BlurredImage entity 1 DAO class for inserting and fetching pictures Database

Please click here for the relevant implementation code.

In Kotlin, we recommend CoroutineWorker if you need to perform asynchronous operations, such as storing data in a database or initiating network requests.

CoroutineWorker performs asynchronous tasks by using Kotlin synergies.

The doWork () method is an suspend method. That is to say, we can call the suspendable dao function here.


/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */

class BlurWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {

    override suspend fun doWork(): Result {
        val resourceUri = inputData.getString(KEY_IMAGE_URI)

        return try {
            if (resourceUri.isNullOrEmpty()) {
                Timber.e("Invalid input uri")
                throw IllegalArgumentException("Invalid input uri")
            }

            val outputData = blurAndWriteImageToFile(resourceUri)
            //  Will  uri  Store to database 
           val imageDao = ImagesDatabase.getDatabase(applicationContext).blurredImageDao()
            imageDao.insert(BlurredImage(resourceUri))

            Result.success(outputData)
        } catch (throwable: Throwable) {
            Timber.e(throwable, "Error applying blur")
            Result.failure()
        }
    }
...
}

doWork () uses Dispatchers. Default by default. You can replace it with the Dispatcher you need. In this case, we don't need to do this because Room already has the data insertion done in another Dispatcher. For more information, please refer to Room Kotlin API.

Start using CoroutineWorker to perform asynchronous tasks, even if the user closes the application, the task can be ensured to complete.

If you want to know more about WorkManager, please pay attention to future related articles. Until then, you can access our codelab and documentation:

WorkManager Documentation Codelab uses WorkManager Codelab WorkManager Advanced

These are the details of Android using Kotlin API to practice WorkManager. For more information about Android practicing WorkManager, please pay attention to other related articles on this site!


Related articles: