关于android:使用-Kotlin-API-实践-WorkManager

38次阅读

共计 3264 个字符,预计需要花费 9 分钟才能阅读完成。

WorkManager 提供了一系列 API 能够更加便捷地布局异步工作,即便在利用被敞开之后或者设施重启之后,依然须要保障立刻执行的或者推延执行的工作被失常解决。对于 Kotlin 开发者,WorkManager 为协程提供了最佳的反对。在本文中,我将通过实际 WorkManager codelab 为大家展现 WorkManager 中与协程相干的基本操作。那么让咱们开始吧!

WorkManager 根底

当您须要某个工作放弃运行状态,即便用户切换到别的界面或者用户将利用切换到后盾,甚至设施重启的时候依然不影响工作状态,那么十分举荐应用 WorkManager。相似的利用场景包含:

  • 上传日志或者报告数据
  • 应用滤镜解决图片的同时保留图片
  • 通过网络定期同步本地数据

如果您的即时工作能够在用户脱离某个作用域时完结,比方切换到其它界面,咱们建议您还是间接应用 Kotlin 协程。

在这个 WorkManager codelab 教程中,咱们会对图片进行模糊化解决,并且将解决后的数据存储在磁盘上。咱们看一下这个过程中须要哪些操作。

增加 work-runtime-ktx 依赖:

// 获取最新的版本号  https://developer.android.google.cn/jetpack/androidx/releases/work
def work_version = "2.5.0"
implementation "androidx.work:work-runtime-ktx:$work_version"

首先实现咱们本人的 Worker 类。咱们会在这里实现真正须要在后盾执行业务的代码。您能够扩大 Worker 类,并且复写 doWork() 办法。因为这个类十分重要,咱们会在后边内容中进行具体介绍。这里是它最后的实现代码。

/* 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()}
    }
…
}

接下来,创立咱们的 work 申请,在本例中,咱们心愿整个操作仅运行一次,所以咱们应用 OneTimeWorkRequest.Builder,将须要模糊化解决的图片的 Uri 作为参数传入。

Kotlin 小贴士 : 要创立输出数据,咱们能够应用 workDataOf 函数,它会帮咱们创立数据构建器,并且填充键值对,而后为咱们创立数据。

/* 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)

咱们应用 WorkManager 类将下面所做的工作增加到打算队列并且运行。咱们能够提供须要执行的工作和这些工作的限度条件。

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

val workManager = WorkManager.getInstance(application)
val continuation = workManager.beginUniqueWork(blurBuilder.build())
// 执行工作
continuation.enqueue()

使 Worker 开始执行工作

当您应用 Worker 的时候,WorkManager 会在后盾线程中主动调用 Worker.doWork()。doWork() 返回的 Result 会告知 WorkManager 服务是否胜利,如果失败则告知是否须要重试。

Worker.doWork() 属于同步调用 — 您的后盾操作须要以阻塞的形式执行,并且所有工作须要在整个 doWork() 函数完结的时候实现。如果您在 doWork() 里调用异步的 API 而后返回后果,那么您回调函数的执行可能会呈现问题。

然而如果我心愿进行异步操作怎么办?

咱们来将下面的示例操作变得复杂一点,比方我心愿在数据库中存储所有进行模糊化解决的文件的 Uri。

所以我创立了:

  • 一个简略的 BlurredImage 实体
  • 一个用于插入和获取图片的 DAO 类
  • 数据库

相干的实现代码请 点击这里。

如果您须要执行异步操作,比方在数据库中存储数据或者发动网络申请,在 Kotlin 中,咱们举荐应用 CoroutineWorker

CoroutineWorker 通过应用 Kotlin 协程来执行异步工作。

doWork() 办法是一个 suspend 办法。也就是说咱们这里能够调用可挂起的 dao 函数。

/* 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)
            // 将 uri 存储到数据库
           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() 默认应用 Dispatchers.Default。您能够将其替换为您所需的 Dispatcher。在这里,咱们不须要这么做,因为 Room 曾经将数据插入操作放在另外的 Dispatcher 中实现了。更多相干内容能够参考 Room Kotlin API。

开始应用 CoroutineWorker 来执行异步工作吧,即便用户敞开利用也能够确保工作实现。

如果您心愿理解更多对于 WorkManager 的内容,请关注将来的相干文章。在那之前,能够拜访咱们的 codelab 和文档:

  • WorkManager 文档
  • Codelab | 应用 WorkManager
  • Codelab | WorkManager 进阶

正文完
 0