iKirby's Blog/

Kotlin Coroutines (协程) 简单使用

之前在闲暇时间自己学了一些 Android 相关的东西,写了一个简单的 IT之家 App ,用来代替日渐臃肿的官方 App (说实话 IT之家 官方 App 算是非常良心了,但是咱有点强迫症)。现在想起来最早写的代码真的是惨不忍睹,网络操作直接 new Thread() ,然后再 runOnUiThread() ,最后自己都看不下去了,换成了 RxJava (由于使用 Jsoup 直接获取电脑版页面并解析,就没有使用 Retrofit)。虽然看上去好了不少,但是 RxJava 里面很多东西我自己也没有搞懂,而且有时候会出现莫名其妙的异常(我把 App 分享给几个朋友之后,经常有人说遇到奇怪问题,但是我自己又测不出来问题,就很烦)。

今年暑假时候学了学 Kotlin ,把整个 App 全部使用 Kotlin 重写了。最近又了解了一下 Kotlin Coroutines ,感觉是个非常棒的东西,而且只用于网络操作的处理的话,比 RxJava 也更加轻量。于是这两天闲下来了,就把使用到 RxJava 的部分换成了 Coroutines ,不仅写起来更简单,代码看起来也更整洁更容易阅读。


Kotlin Coroutines 基于暂停的机制,相应方法被调用时会暂停程序执行,并在执行完成后继续程序的执行。这样就可以以有序的方式写异步代码,不需要搞乱七八糟的回调。它基本使用很简单,就拿我现在的用法来说吧。

需要注意的是,Kotlin Coroutines 还处于实验性阶段,不建议用于生产环境。更新:已经推出了 1.1.0 版本,需要配合 Kotlin 1.3 使用。文章内容已经更新。

添加依赖

对于 Android 项目,在 build.gradle 中添加(最新版本可以在官方 GitHub 仓库看到)

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0'

其中提供了在 Android 上对 UI 线程进行操作所需的 Dispatchers.Main Context 。

修改 Activity 中的代码

首先使需要使用的 Activity 实现 CoroutineScope 接口

open class BaseActivity : AppCompatActivity(), CoroutineScope

然后添加一个 SupervisorJob 的全局变量(用于管理这个 Activity 中全部的 Coroutine),并重写 coroutineContext

private val job = SupervisorJob()
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

接下来在 onDestroy 方法中添加

coroutineContext.cancelChildren()

以便 Activity 结束时取消所有的操作。

做完以上工作,就可以开始使用了。例如:

launch {
    val result = withContext(Dispatchers.IO) { /* 调用网络请求方法 */ }
    // 其他操作,比如直接对 UI 进行操作
}

这样无需修改原先 API 接口的返回值,即可使用 Kotlin Coroutines 了。


文章更新于 2019-01-04 。

留下一条评论

共有 4 条评论

  1. CzBiX:

    我还在用老版本的 coroutines 库,新版本有些地方不兼容。

    2018-10-18 15:42 回复
  2. skylark:

    惊现dalao

    2018-10-25 08:05 回复
    1. Wate:

      刷个留言

      2018-10-29 23:53 回复