Kotlin之Coroutine

综合技术 2018-05-16 阅读原文

1_as86LrhMP7bbf5qsdD38tg.jpeg

定义

Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法。

在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例

配置

build.gradle中dependencies 添加下面2行,注意coroutine目前仍处于experiment阶段,但Kotline官方保证向前兼容。

dependencies { 
     implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'      
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.19.3"   
 }

实例

我们看一个简单Android示例:

activity_coroutine.xml



    

CoroutineActivity.kt

class CoroutineActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_coroutine)

        setup()
    }

    fun setup() {
        launch(UI) { // launch coroutine in UI context
            for (i in 10 downTo 1) { // countdown from 10 to 1
                tvHello.text = "Countdown $i ..." // update text
                delay(1000) // wait half a second
            }
            tvHello.text = "Done!"
        }
    }
}

运行程序 tvHello从10倒计时显示到1,最后显示"Done!"

代码分析:

我们重点分析setup()函数

  • launch(UI) {...} -----在UIcontext下启动coroutine

  • delay(1000) ----将当前coroutine挂起1秒

看到这里你可能会疑惑,Android开发中不是禁止在主线程下做延迟或者阻塞操作吗?

我们回顾下Coroutine的定义: 一个可被挂起的计算实例。

Coroutine不是线程,所以挂起Coroutine不会影响当前线程的运行。

取消Coroutine运行

我们修改下上面的代码:

class CoroutineActivity : AppCompatActivity() {

    lateinit  var job:Job

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_coroutine)

        setup()
    }

    fun setup() {
        job = launch(CommonPool) { // launch coroutine in UI context
            for (i in 10 downTo 1) { // countdown from 10 to 1
                tvHello.text = "Countdown $i ..." // update text
                delay(1000) // wait half a second
            }
            tvHello.text = "Done!"
        }
    }

    override fun onPause() {
        super.onPause()

        job.cancel()
    }
}

重点是 launch(UI)返回给一个job实例,通过job.cancel()取消coroutine。

Coroutine和thread关系

我们再分析下

launch(UI)

这行代码是指将coroutine指派在UI线程上运行

当我们运行一段cpu耗时操作时,则需要将coroutine指定在非UI线程上。

我们写成:

launch(){...}

这行代码等价于:

launch(CommonPool){...}

我们分析下CommonPool的实现,发现它会根据当前cpu的核数创建一个线程池提供给Coroutine使用。

private fun createPlainPool(): ExecutorService {
        val threadId = AtomicInteger()
        return Executors.newFixedThreadPool(defaultParallelism()) {
            Thread(it, "CommonPool-worker-${threadId.incrementAndGet()}").apply { isDaemon = true }
        }
    }

    private fun defaultParallelism() = (Runtime.getRuntime().availableProcessors() - 1).coerceAtLeast(1)

总结:

通过上面的分析,我们理解了Coroutine是一个运行在线程上的可被挂起的计算单元实例,对Coroutine的delay,cancel操作不会影响线程的运行,线程的状态变化对我们是透明的,我们不需要关心。

所以使用Coroutine,可以使我们更加方便得处理异步操作,比如网络请求,数据存储等。

引用:

https://github.com/Kotlin/kotlinx.coroutines

简书

责编内容by:简书阅读原文】。感谢您的支持!

您可能感兴趣的

从Java到Kotlin(四) 对象与泛型 目录 1.对象 1.1 匿名类与对象 1.2 静态类成员与伴生对象 2.泛型 2.1 型变 2.2 类型投影 2.3 泛型函数 2.4 泛型约束 1.对象 1.1 匿名类与...
LottieAndroid使用详解及源码解析 LottieAndroid使用详解及源码解析,让你的应用加载动画变得轻而易举。 我们主要从以下四个方面来讲解: 一、Lottie简介 二、LottieAndroid的使用 三、LottieAndroid源码解析 四、可能...
我试了下在 Android 手机上运行 Node.js 应用……... 「阅」——JSCourse 旗下栏目,专门推荐我们为大家精心挑选的优质 JavaScript 相关技术内容 最近小编入了一部米8,从 iOS 的阵营到了 Android 的阵营,于是就想到了能不能在 Android 手机...
如何在安卓应用中使用 TensorFlow Mobile TensorFlow 是当今最流行的机器学习框架之一,您利用它可以轻松创建和训练深度模型 —— 通常也称为深度前馈神经网络,这些模型可以解决各种复杂问题,如图像分类、目标检测和自然语言理解。TensorFlow Mobile 是一个...
Fragment 知识梳理(3) FragmentPagerAdapter 和 FragmentSt... 在上一篇文章中,我们通过源码的角度了解 FragmentPagerAdapter 和 FragmentStatePagerAdapter 的原理。这其实是为我们 分析数据更新问题 做一个铺垫。 在实际的开发当中,我们在 ViewPager...