基本使用:
// 方法一,使用 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 平台的封装来配合使用)
以上三个方法的共同特点就是,在非协程的代码中开启协程的方法。
操作符/函数 | 描述 |
---|---|
withContext | 这个函数可以在指定的上下文中执行协程代码。例如,可以使用Dispatchers.IO 来在IO线程中执行协程。 |
launch | 用于启动一个新的协程。它会返回一个Job 对象,可以用来取消协程 |
async | 与launch 类似,但它会返回一个Deferred 对象,可以通过调用await() 方法获取协程的结果 |
注意:launch 和 async 是必须在 协程里面开启 才能编译过去,在协程之外开启,编译会报错;withContext则必须在协程或者suspend修饰的方法中使用,否则编译报错。
launch和withContext的区别
在Kotlin协程中,launch
和withContext
是两个用于启动协程的函数,它们之间存在一些差异。具体分析如下:
launch
:launch
函数用于在协程作用域内创建一个新的协程。它不阻塞当前线程,而是将协程任务放入后台执行。launch
通常用于执行不需要返回值的任务,例如在后台执行一些操作而不需要等待结果。launch
函数的特点是它会将协程任务挂起,直到任务完成或者被取消。
withContext
:withContext
函数用于在特定的上下文中执行协程代码块。它可以确保代码块在指定的协程作用域内执行,并且可以使用指定的协程调度器或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) // 模拟耗