Kotlin协程使用

一、开启协程的方式

1、顶层开启协程的函数

基本使用:

// 方法一,使用 runBlocking 顶层函数
runBlocking {
    getImage(imageId)
}
​
// 方法二,使用 GlobalScope 单例对象
//             可以直接调用 launch 开启协程,或者aysnc需要await接收结果
GlobalScope.launch {
    getImage(imageId)
}
​
// 方法三,自行通过 CoroutineContext 创建一个 CoroutineScope 对象
//                                     需要一个类型为 CoroutineContext 的参数
val coroutineScope = CoroutineScope(context)
coroutineScope.launch { //或者async,需要await接收结果
    getImage(imageId)
}
  • 方法一通常适用于单元测试的场景,而业务开发中不会用到这种方法,因为它是线程阻塞的。

  • 方法二和使用 runBlocking 的区别在于不会阻塞线程。但在 Android 开发中同样不推荐这种用法,因为它的生命周期会和 app 一致,且不能取消。

  • 方法三是比较推荐的使用方法,我们可以通过 context 参数去管理和控制协程的生命周期(这里的 context 和 Android 里的不是一个东西,是一个更通用的概念,会有一个 Android 平台的封装来配合使用)

以上三个方法的共同特点就是,在非协程的代码中开启协程的方法。

2、切协程方法/操作符

操作符/函数 描述
withContext 这个函数可以在指定的上下文中执行协程代码。例如,可以使用Dispatchers.IO来在IO线程中执行协程。
launch 用于启动一个新的协程。它会返回一个Job对象,可以用来取消协程
async launch类似,但它会返回一个Deferred对象,可以通过调用await()方法获取协程的结果

注意:launch 和 async 是必须在 协程里面开启 才能编译过去,在协程之外开启,编译会报错;withContext则必须在协程或者suspend修饰的方法中使用,否则编译报错。

launch和withContext的区别

在Kotlin协程中,launchwithContext是两个用于启动协程的函数,它们之间存在一些差异。具体分析如下:

  • launchlaunch函数用于在协程作用域内创建一个新的协程。它不阻塞当前线程,而是将协程任务放入后台执行。launch通常用于执行不需要返回值的任务,例如在后台执行一些操作而不需要等待结果。launch函数的特点是它会将协程任务挂起,直到任务完成或者被取消。

  • withContextwithContext函数用于在特定的上下文中执行协程代码块。它可以确保代码块在指定的协程作用域内执行,并且可以使用指定的协程调度器或Job。withContext通常用于需要切换协程作用域或调度器的场景,例如在IO密集型任务中使用Dispatchers.IO调度器。

import kotlinx.coroutines.*
​
fun main() = runBlocking {
    val job = launch {
        // 在这里执行协程代码
    }
    // 等待协程执行完成
    job.join()
}
​
fun main() = runBlocking {
    val deferred = async {
        // 在这里执行协程代码并返回结果
    }
    // 获取协程的结果
    val result = deferred.await()
    println("Result: $result")
}
​
fun main() = runBlocking {
    withContext(Dispatchers.IO) {
        // 在这里执行协程代码
    }
}
​
 fun test2(){
     val job = GlobalScope.launch {
         // 在这里执行协程代码
         print(t1()+t2())
     }
     Thread.sleep(3000)
     print("After runBlocking ${job.isActive} ")
 }
suspend fun t1() =  withContext(Dispatchers.IO){
    delay(1000L) // 模拟耗时操作
    "After delay 1 "
}
suspend fun t2() = withContext(Dispatchers.IO){
    delay(2000L) // 模拟耗

你可能感兴趣的:(Kotlin协程使用)