Android使用Kotlin API实践WorkManager

 更新时间:2021年04月15日 09:16:51   作者:Android_开发者  
这篇文章主要介绍了Android使用Kotlin API实践WorkManager的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

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 和文档:

以上就是Android使用Kotlin API实践WorkManager的详细内容,更多关于Android实践WorkManager的资料请关注脚本之家其它相关文章!

相关文章

  • 基于android布局中的常用占位符介绍

    基于android布局中的常用占位符介绍

    下面小编就为大家分享一篇基于android布局中的常用占位符介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android ViewPager动态加载问题

    Android ViewPager动态加载问题

    这篇文章主要介绍了Android ViewPager动态加载问题,需要的朋友可以参考下
    2017-03-03
  • Android视频悬浮窗口实现的示例代码

    Android视频悬浮窗口实现的示例代码

    这篇文章主要介绍了Android视频悬浮窗口实现的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • OpenGL Shader实现物件材料效果详解

    OpenGL Shader实现物件材料效果详解

    在一些主流app上有一些比较特殊的滤镜效果,例如灰尘、塑料封面、光影效果等,这些其实是纹理叠加的效果。本文将用OpenGL Shader实现这些效果,需要的可以参考一下
    2022-02-02
  • Android Dialog详解及实例代码

    Android Dialog详解及实例代码

    这篇文章主要介绍了 Android Dialog详解及实例代码的相关资料,需要的朋友可以参考下
    2017-04-04
  • Android系统设置中的清除数据会清除哪些数据?

    Android系统设置中的清除数据会清除哪些数据?

    这篇文章主要介绍了Android系统设置中的清除数据会清除哪些数据?本文对比了清除前和清除后的数据情况,从而得出到底清除了哪些数据,需要的朋友可以参考下
    2015-01-01
  • Android如何获取APP启动时间

    Android如何获取APP启动时间

    大家好,本篇文章主要讲的是Android如何获取APP启动时间,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • Android仿苹果关机界面实现代码

    Android仿苹果关机界面实现代码

    这篇文章主要为大家详细介绍了Android仿苹果关机界面的实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • Android评分RationBar控件使用详解

    Android评分RationBar控件使用详解

    这篇文章主要为大家详细介绍了Android评分RationBar控件的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • RecyclerView设置间距和添加分割线的方法

    RecyclerView设置间距和添加分割线的方法

    在使用RecyclerView布局,经常需要调整间距和添加分割线以达到更美观效果,这篇文章主要介绍了RecyclerView设置间距和添加分割线的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09

最新评论