• 【深入理解Kotlin协程】协程调度器Dispatchers源码追踪扒皮


    Android中的Kotlin协程调度器主要有四种: Dispatchers.Main、 Dispatchers.Default、 Dispatchers.IO、 Dispatchers.Unconfined,第四种平时开发应该一般不会用到,所以主要了解一下前3种的实现。

    Dispatchers.Main

    public actual val Main: MainCoroutineDispatcher get() = MainDispatcherLoader.dispatcher
    1. // MainDispatchers.kt
    2. internal object MainDispatcherLoader {
    3.     private val FAST_SERVICE_LOADER_ENABLED = systemProp(FAST_SERVICE_LOADER_PROPERTY_NAME, true)
    4.     @JvmField
    5.     val dispatcher: MainCoroutineDispatcher = loadMainDispatcher()
    6.     private fun loadMainDispatcher(): MainCoroutineDispatcher {
    7.         return try {
    8.             val factories = if (FAST_SERVICE_LOADER_ENABLED) {
    9.                 FastServiceLoader.loadMainDispatcherFactory()
    10.             } else {
    11.                 // We are explicitly using the
    12.                 // `ServiceLoader.load(MyClass::class.java, MyClass::class.java.classLoader).iterator()`
    13.                 // form of the ServiceLoader call to enable R8 optimization when compiled on Android.
    14.                 ServiceLoader.load(
    15.                         MainDispatcherFactory::class.java,
    16.                         MainDispatcherFactory::class.java.classLoader
    17.                 ).iterator().asSequence().toList()
    18.             }
    19.             @Suppress("ConstantConditionIf")
    20.             factories.maxByOrNull { it.loadPriority }?.tryCreateDispatcher(factories)
    21.                 ?: createMissingDispatcher()
    22.         } catch (e: Throwable) {
    23.             // Service loader can throw an exception as well
    24.             createMissingDispatcher(e)
    25.         }
    26.     }
    27. }

    可以看到Dispatchers.Main就是单例对象MainDispatcherLoader.loadMainDispatcher()方法的返回值,该方法会通过MainDispatcherFactory去创建一个MainCoroutineDispatcher对象。因此Dispatchers.Main属于MainCoroutineDispatcher类型。MainDispatcherFactory是一个抽象接口,它的实现类是AndroidDispatcherFactory,如下:

    1. internal class AndroidDispatcherFactory : MainDispatcherFactory {
    2.     override fun createDispatcher(allFactories: List<MainDispatcherFactory>): MainCoroutineDispatcher {
    3.         val mainLooper = Looper.getMainLooper() ?: throw IllegalStateException("The main looper is not available")
    4.         return HandlerContext(mainLooper.asHandler(async = true))
    5.     }
    6.     override fun hintOnError(): String = "For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used"
    7.     override val loadPriority: Int
    8.         get() = Int.MAX_VALUE / 2
    9. }

    很明显这里createDispatcher方法创建了一个HandlerContext对象返回,并且我们注意到,它使用主线程的Looper对象来创建的Handler

    事实上  Dispatchers.Main 是一个多平台化的 API,在 Android、JavaFX、Swing等场景下实现的细节都不同,我们用 Intelij IDEA 打开 kotlinx.coroutines 项目的源码,这三者的实现都位于 ui 这个目录下。我们在 kotlinx.coroutines.android 包下找到了 HandlerDispatcher.kt 这个代码文件, HandlerContext的具体实现就在其中。
             
    因此,我们可以得到一个结论就是:在 Android 平台上  Dispatchers.Main 就是一个  HandlerContext 对象。
            
    HandlerContext的主要源码如下:
    1. // HandlerDispatcher.kt
    2. internal class HandlerContext private constructor(
    3.     private val handler: Handler,
    4.     private val name: String?,
    5.     private val invokeImmediately: Boolean
    6. ) : HandlerDispatcher(), Delay {
    7.     constructor(
    8.         handler: Handler,
    9.         name: String? = null
    10.     ) : this(handler, name, false)
    11.     @Volatile
    12.     private var _immediate: HandlerContext? = if (invokeImmediately) this else null
    13.     override val immediate: HandlerContext = _immediate ?:
    14.         HandlerContext(handler, name, true).also { _immediate = it }
    15.     override f
  • 相关阅读:
    final finally finalize 区别?
    HttpClient笔记
    Failed to start The nginx HTTP and reverse proxy server.
    Windows证书过期【解决方法】
    4.2冰达机器人:视觉实例-机器人视觉循线、视觉实例-调整循线颜色
    【全民Python】Python环境配置和Pychram的安装使用
    JAVASE语法零基础——封装与包
    LVS+Keepalived+nfs 集群部署及实验
    【PostgreSql基础语法 】1、增删改查、where、limit、like模糊查询
    Kamiya丨Kamiya艾美捷人α1-抗糜蛋白酶ELISA说明书
  • 原文地址:https://blog.csdn.net/lyabc123456/article/details/127868825