Kotlin协程是什么
简单理解就是一个"线程框架",由Kotlin官方提供的线程API,类似Java的Executor和Android的AsyncTask.
为什么使用它呢?方便,特别是它可以用看起来同步的方式写出异步代码,这也是人们常说的非阻塞式挂起.
这里举个例子,通过接口请求获取名字,然后显示在TextView上
正常使用:
api.getUser()
.enqueue(object: Callback{
override fun onFailure(){
}
override fun onResonse(Resonse response){
runOnUiThread{
nameTv.text=response.body()?.name
}
}
}
)
使用协程:
GlobalScope.launch() {
//网络请求(IO 线程)
val user = api.getUser()
//更新 UI(主线程)
nameTv.text = user.name
}
省去了回调,同时看上去跟同步请求差不多,很清晰
还比如下面这种场景,同时请求A,B两个接口,两个接口都请求完毕后整合数据并显示,如果我们不使用协程,那么我们一般就是改成顺序请求,因为并发请求不太好弄,这样就会消耗一些时间,同时还会有回调嵌套的问题;如果使用协程呢,就可以完美实现
GlobalScope.launch(Dispatchers.Main) {
// 获取A接口
val A = async { api.getA() }
// 获取B接口
val B = async { api.getB() }
// 合并结果
val merged = erge(A, B)
// 更新 UI
show(merged)
}
Kotlin协程怎么用
引入库
项目根目录下的 build.gradle :
buildscript {
...
ext.kotlin_coroutines = '1.3.1'
...
}
Module 下的 build.gradle :
// 依赖协程核心库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines"
// 依赖当前平台所对应的平台库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines"
使用
创建协程
// 方法一,使用 runBlocking 顶层函数
//通常适用于单元测试的场景,而业务开发中不会用到这种方法,因为它是线程阻塞的
runBlocking {
}
// 方法二,使用 GlobalScope 单例对象
GlobalScope.launch {
}
// 方法三,自行通过 CoroutineContext 创建一个 CoroutineScope 对象
// 需要一个类型为 CoroutineContext 的参数
val coroutineScope = CoroutineScope(context)
coroutineScope.launch {
}
这个 launch 函数表示我要创建一个新的协程,并在指定的线程上运行它。这个被创建、被运行的所谓「协程」是谁?就是你传给 launch 的那些代码,这一段连续代码叫做一个「协程」。
切线程
coroutineScope.launch(Dispatchers.Main) {
...
withContext(Dispatchers.IO) {
...
}
...
withContext(Dispatchers.IO) {
...
}
...
}
我们也可以把withContext放在一个函数里面.但是这个函数必须使用suspend
suspend fun getImage() {
withContext(Dispatchers.IO) {
}
}
这个suspend是 Kotlin 协程最核心的关键字,代码执行到 suspend 函数的时候会『挂起』,并且这个『挂起』是非阻塞式的,它不会阻塞你当前的线程。