3.2-CoroutineScope/CoroutineContext:GlobalScope

文章目录

GlobalScope 是一个特殊的 CoroutineScope,它是一个单例的 CoroutineScope,我们可以直接用它启动协程:

fun main() = runBlocking {
	GlobalScope.launch {}
	delay(10000)
}

我们在 IDE 用 GlobalScope 时会有一条黄线,提示的是要小心使用它因为容易用错、容易写出问题:

在这里插入图片描述

当然我们理解了它的作用和适用场景后,是可以放心的使用它的。

前面讲解过的 CoroutineScope 调用 launch 启动的协程基本都会有内置的 Job,无论是自定义创建的 CoroutineScope,还是协程提供给我们的 CoroutineScope:

val scope = CoroutineScope(EmptyCoroutineContext)
val outerJob = scope.launch {
    val innerJob = coroutineContext[Job] // 一定会有 Job
    println("innerJob = $innerJob")
}
println("outerJob = $outerJob")

输出结果:
innerJob = StandaloneCoroutine{Active}@918c79d
outerJob = StandaloneCoroutine{Active}@918c79d

在这里插入图片描述

我们简单看下 GlobalScope 的源码:

CoroutineScope.kt

@DelicateCoroutinesApi
public object GlobalScope : CoroutineScope {
	
	// 重写了 coroutineContext,直接返回了 EmptyCoroutineContext
	override val coroutineContext: CoroutineContext
		get() = EmptyCoroutineContext
}

可以看到 GlobalScope 重写了 coroutineContext,直接返回了 EmptyCoroutineContext。所以说 GlobalScope 真正的特点是它没有内置的 Job,因为 coroutineContext 就是一个空的上下文,自然也没有 Job。

在这里插入图片描述

没有 Job 的 CoroutineScope 有什么作用呢?没有 Job 说明它创建的协程就没有父协程,确切的说它创建的协程的 Job 就没有父 Job

@OptIn(DelicateCoroutinesApi::class)
fun main() = runBlocking {
    val job = GlobalScope.async {
        delay(1000)
    }
    println("job parent = ${job.parent}")
}

输出结果:
job parent = null

GlobalScope 的使用场景:在不需要和生命周期绑定又想启动协程的地方使用,因为没有父 Job 也就不会因任何组件的关闭而自动取消协程。CoroutineScope(EmptyCoroutineContext).launch 这么写又比较麻烦,所以提供了GlobalScope。使用它时做好及时关闭协程即可,并不是不能使用的东西

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值