WorkManager 在 Kotlin 中的实践

浩浩 等级 1022 0 0

WorkManager 是一个 Android Jetpack 扩展库,它可以让您轻松规划那些可延后、异步但又需要可靠运行的任务。对于绝大部分后台执行任务来说,使用 WorkManager 是目前 Android 平台上的最佳实践。

在这篇文章中,我们将讨论:

Kotlin 版的 WorkManager

本文的示例代码是用 Kotlin 编写的并使用了 KTX 库 (Kotlin Extensions)。KTX 版的 WorkManager 提供了更简洁且惯用的 Kotlin 扩展函数。如 WorkManager 发布日志中描述的那样,只需要在 build.gradle 文件中添加 androidx.work:work-runtime-ktx 依赖项,即可使用 KTX 版的 WorkManager。该组件包含 CoroutineWorker 和其他有用的 WorkManager 扩展方法。

更简洁且惯用

当您需要构造一个数据对象,并且需要将它传入Worker 类或者从 Worker 类返回时,KTX 版 WorkManager 提供了一种语法糖。在这种情况下,用 Java 语法实现的代码如下所示:


Data myData = new Data.Builder()
                      .putInt(KEY_ONE_INT, aInt)
                      .putIntArray(KEY_ONE_INT_ARRAY, aIntArray)
                      .putString(KEY_ONE_STRING, aString)
                      .build();

而在 Kotlin 中,我们可以借助 workDataOf 辅助函数将代码写的更简洁:


inline fun workDataOf(vararg pairs: Pair<String, Any?>): Data

因此可以将前面的 Java 表达式改写成:


val data = workDataOf(
        KEY_MY_INT to myIntVar,
        KEY_MY_INT_ARRAY to myIntArray,
        KEY_MY_STRING to myString
    )

CoroutineWorker

除了可以使用 Java 实现的 Worker 类 (Worker、ListenableWorker 和 RxWorker) 之外,还有唯一一个使用 Kotlin 协程实现的 Work 类——CoroutineWorker。

Worker 类与 CoroutineWorker 类的主要区别在于: CoroutineWorker 类的 doWork() 方法是一个可以执行异步任务的挂起函数,而 Worker 类的 doWork() 方法只能执行同步任务。CoroutineWorker 的另一个特性是可以自动处理任务的暂停和取消,而 Worker 类需要实现 onStopped() 方法来处理这些情况。

获得完整上下文信息,请参阅官方文档在 WorkManager 中进行线程处理。在这里,我想重点介绍一下什么是 CoroutineWorker,并且涵盖一些细小的但很重要的区别,以及深入了解如何使用在 WorkManager v2.1 中引入的新测试特性,来测试您的 CoroutineWorker 类。

正如前面写的那样,CoroutineWorker#doWork() 只是一个挂起函数。它默认是在 Dispatchers.Default 上启动的:


class MyWork(context: Context, params: WorkerParameters) :
        CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
            // 做点什么
            Result.success()
        } catch (error: Throwable) {
            Result.failure()
        }
    }
}

需要切记的是,这是使用 CoroutineWorker 代替 Worker 或 ListenableWorker 时的根本区别:

与 Worker 不同,此代码不会在 WorkManager 的 Configuration 中指定的 Executor 上运行。

正如刚才所说,CoroutineWorker#doWork() 默认是在 Dispatchers.Default 启动的。您可以使用 withContext() 对此配置进行自定义。


class MyWork(context: Context, params: WorkerParameters) :
        CoroutineWorker(context, params) {
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
return try {
            // 做点什么
            Result.success()
        } catch (error: Throwable) {
            Result.failure()
        }
    }
}

很少需要改变 CoroutineWorker 使用的 Dispatcher,因为 Dispatchers.Default 可以满足大多数情况下的需求。

要了解关于如何在 Kotlin 中使用 WorkManager,可以尝试这个 codelab。

总结

随着 WorkManager v2.1 以及 workManager-testing 中新特性的发布,CoroutineWorker 因其简单易用而大放光彩。现在您可以非常容易的对 Worker 类进行测试,并且 WorkManager 在 Kotlin 中的整体使用体验也非常棒。

如果您还没有在项目中使用 CoroutineWorker 以及 workmanager-runtime-ktx 中包含的其他扩展,强烈建议您在项目中使用它们。当使用 Kotlin 进行开发 (已经成为我的日常) 时,这是我使用 WorkManager 的首选方式。

希望这篇文章对您有所帮助,欢迎您在评论区积极留言,分享您在 WorkManager 使用中的见解或者问题。

WorkManager 相关资源

开发者指南 | 在 WorkManager 中进行线程处理 参考指南 | androidx.work Codelab | 使用 WorkManager 处理后台任务 WorkManager 的公开问题追踪器 发行日志 | WorkManager Stack Overflow 的 [android-workmanager] 标签 WorkManager 的源码 (AOSP的一部分)

收藏
评论区

相关推荐

WorkManager 在 Kotlin 中的实践
WorkManager 是一个 Android Jetpack 扩展库,它可以让您轻松规划那些可延后、异步但又需要可靠运行的任务。对于绝大部分后台执行任务来说,使用 WorkManager 是目前 Android 平台上的最佳实践。 WorkManager https://developer.android.google.cn/topic/libra
Better Kotlin
本文由  南尘 授权转载发布 第59次推文 贺贺 转眼间使用 Kotlin 已经有两个月了,时间不长,我也算搭上了 Google 宣布 Kotlin 作为官方支持语言的一波末班车。可能大家早已从纯 Java 开发 Android 转为了混合使用开发甚至是 Kotlin 开发,那你转向 Kotlin 的初衷又是什么呢? 对于我,很简单,
Kotlin 1.4.30
**关键词:Kotlin News** > 内联类从 1.3 推出,一直处于实验状态。 内联类 inline class,是从 Kotlin 1.3 开始加入的实验特性,计划 1.4.30 进入 Beta 状态(看来 1.5.0 要转正了?)。 内联类要解决的问题呢,其实也与以往我们接触到的内联函数类似,大体思路就是提供某种语法,提升代码编写体验和效率
Kotlin Hello World
1 Kotlin ======== Kotlin是一种在JVM上运行的静态类型编程语言,被称为Android界的Wsift,由JetBrains设计。Kotline可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。Google宣布在Google I/O 2017上宣布Kotlin成为Android官方语言。 笔者不
Kotlin Primer·第五章·函数与闭包
国内目前已经有几家公司开始大规模使用 Kotlin 开发,沪江就是其中一个。本文来自沪江工程师之手,且看他怎么认识 Kotlin,欢迎大家关注他的博客——http://kymjs.com/ ,也欢迎大家关注 Kotlin 中文博客 http://www.kotliner.cn/ * * * 函数与闭包的特性可以算是 Kotlin 语言最大的特性了
Kotlin 使用命令行执行 kts 脚本
运行 REPL(交互式解释器) --------------- 我们可以运行如下命令得到一个可交互的 shell,然后输入任何有效的 Kotlin 代码,并立即看到结果 ![1233356-54fe451bc2e4287e.png](https://oscimg.oschina.net/oscnet/up-5a637703f0af06d956ea7ab9
Kotlin 协程真的比 Java 线程更高效吗?
> 本文首发于 vivo互联网技术 微信公众号  > 链接:[https://mp.weixin.qq.com/s/-OcCDI4L5GR8vVXSYhXJ7w](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fmp.weixin.qq.com%2Fs%2F-OcCDI4L5GR8vVX
Kotlin与ButterKinfe的混合使用
在学习Kotlin开发Android应用的过程中,势必要配合很多Android的开源框架一起使用,而ButterKnife是其中可能会经常用到的一个框架。 但是如果在Kotlin中直接使用ButterKnife的注解方式的话,会出现空指针的异常,导致绑定失败。 那么要如何才能在Kotlin的环境中使用ButterKinfe呢? 不要慌,ButterKn
Kotlin代码检查在美团的探索与实践
背景 -- Kotlin有着诸多的特性,比如空指针安全、方法扩展、支持函数式编程、丰富的语法糖等。这些特性使得Kotlin的代码比Java简洁优雅许多,提高了代码的可读性和可维护性,节省了开发时间,提高了开发效率。这也是我们团队转向Kotlin的原因,但是在实际的使用过程中,我们发现看似写法简单的Kotlin代码,可能隐藏着不容忽视的额外开销。本文剖析了K
Kotlin学习笔记
1 概述 ==== 这篇文章首先会介绍Kotlin的特点,接着介绍Kotlin与Java的语法比较。 2 Kotlin特点 ========== * 一门现代化的编程语言 * 可开发跨平台应用,web,Socket,安卓,js,NativeApp等 * 静态编程语言,性能基本与原声Java相当 * 100%兼容Java(说是兼容但实际上
Kotlin注解深入解析与实例剖析
在上一次[https://www.cnblogs.com/webor2006/p/11522798.html](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fwww.cnblogs.com%2Fwebor2006%2Fp%2F11522798.html)中学习了Kotlin注解相关的东东,
Kotlin简单使用EventBus3.x
> 我的博客原文地址:[Kotlin简单使用EventBus3.x](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fdongxi520.com%2F2017%2F11%2F24%2FKotlin%25E7%25AE%2580%25E5%258D%2595%25E4%25BD%25BF%25E
Spring Boot 与 Kotlin 上传文件
如果我们做一个小型的web站,而且刚好选择的kotlin 和Spring Boot技术栈,那么上传文件的必不可少了,当然,如果你做一个中大型的web站,那建议你使用云存储,能省不少事情。 这篇文章就介绍怎么使用kotlin 和Spring Boot上传文件 构建工程 ---- > 如果对于构建工程还不是很熟悉的可以参考[《我的第一个Kotlin应用》]
Spring Boot 与 Kotlin 验证web表单信息
在做web开发的时候,我们需要验证表单,确认用户提交的信息是安全的,比如用户名不能超过多少位,密码不能少于多少位等等。 那么如何在Spring Boot 与 Kotlin中验证表单信息? 在springmvc工程中,需要检查表单信息,表单信息验证主要通过注解的形式。 表单验证 ---- 下面我们在之前[《Spring Boot 与 kotlin 使用
Spring Boot与Kotlin 整合全文搜索引擎Elasticsearch
Elasticsearch 在全文搜索里面基本是无敌的,在大数据里面也很有建树,完全可以当nosql(本来也是nosql)使用。 这篇文章简单介绍Spring Boot使用Kotlin语言连接操作 Elasticsearch。但是不会做很详细的介绍,如果要深入了解Elasticsearch在Java/kotlin中的使用,请参考我之前编写的《Elastic