public val coroutineContext: CoroutineContext
}
可以看出CoroutineScope
的代码很简单,主要作用是提供CoroutineContext
,协程运行的上下文
我们常见的实现有GlobalScope
,LifecycleScope
,ViewModelScope
等
1.2 GlobalScope
与ViewModelScope
有什么区别?
public object GlobalScope : CoroutineScope {
/**
- 返回 [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
public val ViewModel.viewModelScope: CoroutineScope
get() {
val scope: CoroutineScope? = this.getTag(JOB_KEY)
if (scope != null) {
return scope
}
return setTagIfAbsent(
JOB_KEY,
CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
)
}
两者的代码都挺简单,从上面可以看出
1.GlobalScope
返回的为CoroutineContext
的空实现
2.ViewModelScope
则往CoroutineContext
中添加了Job
与Dispatcher
我们先来看一段简单的代码
fun testOne(){
GlobalScope.launch {
print(“1:” + Thread.currentThread().name)
delay(1000)
print(“2:” + Thread.currentThread().name)
}
}
//打印结果为:DefaultDispatcher-worker-1
fun testTwo(){
viewModelScope.launch {
print(“1:” + Thread.currentThread().name)
delay(1000)
print(“2:” + Thread.currentThread().name)
}
}
//打印结果为: main
上面两种Scope
启动协程后,打印当前线程名是不同的,一个是线程池中的一个线程,一个则是主线程
这是因为ViewModelScope
在CoroutineContext
中添加了Dispatchers.Main.immediate
的原因
我们可以得出结论:协程就是通过Dispatchers
调度器来控制线程切换的
1.3 什么是调度器?
从使用上来讲,调度器就是我们使用的Dispatchers.Main
,Dispatchers.Default
,Dispatcher.IO
等
从作用上来讲,调度器的作用是控制协程运行的线程
从结构上来讲,Dispatchers
的父类是ContinuationInterceptor
,然后再继承于CoroutineContext
它们的类结构关系如下: