Androdi kotlin Coroutines(协程)详解 (四)

Androdi kotlin Coroutines(协程)详解 (一)
Androdi kotlin Coroutines(协程)详解 (二)
Androdi kotlin Coroutines(协程)详解 (三)
Androdi kotlin Coroutines(协程)详解 (四)
Androdi kotlin Coroutines(协程)详解 (五)
Androdi kotlin Coroutines(协程)详解 (六)

四、 CoroutineContext协程上下文

协同程序的持久上下文。它是[Element]实例的索引集,是一些元素的集合。索引集是集和映射的混合。这个集合中的每个元素都有一个唯一的[键]。

内部代码如下:

    @SinceKotlin("1.3")
    public interface CoroutineContext {
        public operator fun <E : Element> get(key: Key<E>): E?
        public fun <R> fold(initial: R, operation: (R, Element) -> R): R
        public operator fun plus(context: CoroutineContext): CoroutineContext = ...
        public fun minusKey(key: Key<*>): CoroutineContext
        public interface Key<E : Element>
        public interface Element : CoroutineContext {
            public val key: Key<*>
            ...
        }
    }

CoroutineContext 作为一个集合,它的元素就是源码中看到的 Element,每一个Element 都有一个 key,因此它可以作为元素出现,同时它也是 CoroutineContext 的子接口,因此也可以作为集合出现。几个重要的子类:

4.1 CoroutineContext.Element

CoroutineContext的一个元素。协同程序上下文的元素本身就是一个单例上下文。

4.2 ContinuationInterceptor 协程拦截器

是 Element 的子类,拦截对象是 Continuation

    public interface ContinuationInterceptor : CoroutineContext.Element {
        companion object Key : CoroutineContext.Key<ContinuationInterceptor>
        public fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T>
        ...
    }

4.3 CoroutineDispatcher 协程调度器

继承了类 AbstractCoroutineContextElement ,实现了 ContinuationInterceptor 接口,先拦截再调度。所以如果我们想要实现自己的调度器,继承这个类就可以了,不过通常我们都用现成的,它们定义在 Dispatchers 当中:

val Default: CoroutineDispatcher
val Main: MainCoroutineDispatcher
val Unconfined: CoroutineDispatcher
val IO: CoroutineDispatcher
JVM
Dispatchers.IO 线程池
Dispatchers.Main UI线程,Android中的主线程
Dispatchers.Default 默认执行线程,线程池
Dispatchers.Unconfined 直接执行

Dispatchers.Main比如在Android中的实现,最终是在 AndroidDispatcherFactory 类中,源码如下:

internal class AndroidDispatcherFactory : MainDispatcherFactory {

    override fun createDispatcher(allFactories: List<MainDispatcherFactory>) =
        HandlerContext(Looper.getMainLooper().asHandler(async = true), "Main")

    override fun hintOnError(): String? = "For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used"

    override val loadPriority: Int
        get() = Int.MAX_VALUE / 2
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容