1.why
在处理异步代码的时候,可能会产生回调地狱。利用Coroutines可以优雅的用同步的编码方式来写异步的代码
2.what
一种线程框架
3.how
3.0 添加依赖
//项目根目录下的 build.gradle
buildscript {
...
ext.kotlin_coroutines = '1.3.1'
...
}
//Module 下的 build.gradle
dependencies {
...
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines"
...
}
3.1 创建协程
// 方法一,使用 runBlocking 顶层函数(线程阻塞)
runBlocking {
getImage(imageId)
}
// 方法二,使用 GlobalScope 单例对象(线程非阻塞,生命周期与app一致,无法取消)
GlobalScope.launch {
getImage(imageId)
}
// 方法三,自行通过 CoroutineContext 创建一个 CoroutineScope 对象(可以控制生命周期)
val coroutineScope = CoroutineScope(context)
coroutineScope.launch {
getImage(imageId)
}
//方法四
val avatar: Deferred = async { api.getAvatar(user) }
3.2 使用
override fun onCreate(savedInstanceState: Bundle?) {
...
GlobalScope.launch(Dispatchers.Main) {
println("当前线程名称:${Thread.currentThread().name}")//main
println("调用方法:${getChildThreadName()}")//main
}
...
}
private suspend fun getChildThreadName():String {
withContext(Dispatchers.IO) {//挂起结束后会重新切换到原来的线程
println("我是挂起函数中的线程:${Thread.currentThread().name}")//DefaultDispatcher-worker-1
}
return Thread.currentThread().name//main
}
4.挂起函数
4.1 定义
使用suspend修饰的函数
4.2 what
- 挂起函数必须要在协程中直接或间接(在挂起函数中)调用
- 挂起的本质就是暂时脱离当前线程,切换到指定线程执行完之后会自动切换到原来的线程
5.其他
非阻塞式?
用看是阻塞的代码实现了非阻塞式的逻辑