Kotlin协程

170 阅读1分钟

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.其他

非阻塞式? 用看是阻塞的代码实现了非阻塞式的逻辑