因为某些协程的实现使用了任务分发,
public fun CoroutineScope.launch (
context : CoroutineContext = EmptyCoroutineContext
Job
协程的后台工作 、 可以用来将协程取消
默认值: Null,
public interface ContinuationInterceptor : CoroutineContext.Element
负责线程的输入、输出, Dispatcher继承于CoroutineDispatcher, 通常使用Dispatcher去指定对应的协程执行线程。
自定义CorountineContext
上下文的切换
CoroutineContext的创建
默认的CorountineContext
通过CoroutineScope的launch和async去创建一个协程,
继承
加号操作符返回一个包含两个上下文所有elements的上下文集合, 当两个上下文有key值相同的element时, 它将丢掉操作符左侧上下文中的element,
CouroutineContext表示协程的上下文,
CoroutineContext可以自由组装使用运算符+/plus的方式进行拼接, 并在启动协程的时候指定
当在协程中刚创建一个子协程时, 子协程的上下文则由指定的子协程作用域与父上下文组合生成
CoroutineExceptionHandler
错误处理
Async在根协程使用时,异常不会被自动抛出,而是直到你调用await()时才抛出,
val scope = CoroutineScope(job())
scope.launch{
async {
}
}
如果async发生了异常,会立即抛出,因为scope的直接子协程是由scope.launch启动的, async继承了协程的上下文中的job,
uiContext : 用于执行UI相关操作
bgContext: 用于执行需要在后台运行的耗时操作。
private fun loadData() = launch(uiContext) {
view.showLoading()
val task = async(bgContext) { dataProvider.loadData("Task") }
val result: Result<String> = task.await() //non ui thread, suspend until the task is finished.
if(result.success != null ){
view.showData(result.success)
} else if (result.error != null) {
result.error.printStackTrace()
}
}
什么是调度器
调度器就是控制协程运行的线程,从结构上来讲, Dispatchers的父类是ContinuationInterceptor,然后再继承与CoroutnineContext, 它的结构:
Continuation
context: CoroutineContext
fun resumeWith(Result)
调度器的具体实现
CoroutineDispatcher是通过CoroutineContext取出来的,这也是协程上下文作用的体现
internal class HandlerContext private constructor {
private val handler : Handler,
private val name : String? ,
private val invokeImmediately: Boolean
}: HandlerDispatcher(), Delay{
public constructor(
handler: Handler,
name: String? = null
): this (handler, name, false) {
向CoroutineContext添加dispatcher, 指定运行的协程,
在启动时将suspend block创建成continuation,
DispatchedContinuation就是对原有协程的装饰,在这里调用Dispatcher
invokeOnTimeout显然是调度过程中发现时间到了以后要恢复执行的方法体。
internal abstract class EventLoopBase: CoroutineDispatcher()