一学就会的协程使用——基础篇(二)线程切换

1. 切换线程执行代码

本文内容很简单,主角即为withContext函数的用法!

前文介绍了怎么启动协程,这部分主要介绍在协程执行过程中切换线程去执行代码以及效果。

上代码:

GlobalScope.launch(Dispatchers.IO) {
    val msgIO = "coroutine runs in IO" // A
    myLog(msgIO)
    val ret = withContext(Dispatchers.Main) {
        val msgWithMain = "withContext in Main" // B
        myLog(msgWithMain)
    }
    myLog(ret) // C
}

这样一段代码,可以确保输出顺序必为 A-B-C而不会乱序!

具体的输出log内容如下:

D/chenhj: coroutine runs in IO ::running in Thread:[id:2886][name:DefaultDispatcher-worker-1]
D/chenhj: withContext in Main ::running in Thread:[id:2][name:main]
D/chenhj: withContext in Main ::running in Thread:[id:2886][name:DefaultDispatcher-worker-1]

注意,第三行日志输出,执行线程将回到了IO线程中。

同样的,可以先启动一个执行在主线程里的协程再切换到IO线程:

GlobalScope.launch(Dispatchers.Main) {
    val msgMain = "coroutine runs in Main"
    myLog(msgMain)
    val ret = withContext(Dispatchers.IO) {
        val msgWithIO = "withContext in IO"
        myLog(msgWithIO)
        msgWithIO
    }
    myLog(ret)
}

同样的,前后三处log输出顺序必然确定,如下:

D/chenhj: coroutine runs in Main ::running in Thread:[id:2][name:main]
D/chenhj: withContext in IO ::running in Thread:[id:2886][name:DefaultDispatcher-worker-1]
D/chenhj: withContext in IO ::running in Thread:[id:2][name:main]

2. 需要注意的点

简单点,需要有以下印象:

  • withContext是个挂起函数;
  • withContext必然有返回值,返回的内容是lambda表达式函数体中最后一个表达式的返回内容;
  • withContext本质上是挂起当前协程并启动新协程去执行逻辑,而不是调度协程到其他线程中;

挂起函数是协程非常核心的内容,后面内容会逐步介绍。

如对函数类型以及lambda表达式并不熟悉,建议自行熟悉学习了解Kotlin中函数式编程的相关设计,协程中的很多富有实用性和易用性的内容,都将与函数式编程中相关。

3. 样例工程代码

代码样例Demo,见Github:https://github.com/TeaCChen/CoroutineStudy

本文示例代码,如觉奇怪或啰嗦,其实为WithContextActivity.kt中的代码摘取主要部分说明,在demo代码当中,为提升细节内容,有更加多的封装和输出内容。

本文对应的页面截图如下:


image-2-1.png

一学就会的协程使用——基础篇

一学就会的协程使用——基础篇(一)协程启动

一学就会的协程使用——基础篇(二)线程切换(本文)

一学就会的协程使用——基础篇(三)初遇协程取消

一学就会的协程使用——基础篇(四)协程作用域

一学就会的协程使用——基础篇(五)再遇协程取消

一学就会的协程使用——基础篇(六)初识挂起

一学就会的协程使用——基础篇(七)初识结构化

一学就会的协程使用——基础篇(八)初识协程异常

一学就会的协程使用——基础篇(九)异常与supervisor

你可能感兴趣的:(一学就会的协程使用——基础篇(二)线程切换)