Android中的Kotlin协程调度器主要有四种:
Dispatchers.Main、
Dispatchers.Default、
Dispatchers.IO、
Dispatchers.Unconfined,第四种平时开发应该一般不会用到,所以主要了解一下前3种的实现。
Dispatchers.Main
public actual val Main: MainCoroutineDispatcher get() = MainDispatcherLoader.dispatcher
// MainDispatchers.kt
internal object MainDispatcherLoader {
private val FAST_SERVICE_LOADER_ENABLED = systemProp(FAST_SERVICE_LOADER_PROPERTY_NAME, true)
@JvmField
val dispatcher: MainCoroutineDispatcher = loadMainDispatcher()
private fun loadMainDispatcher(): MainCoroutineDispatcher {
return try {
val factories = if (FAST_SERVICE_LOADER_ENABLED) {
FastServiceLoader.loadMainDispatcherFactory()
} else {
// We are explicitly using the
// `ServiceLoader.load(MyClass::class.java, MyClass::class.java.classLoader).iterator()`
// form of the ServiceLoader call to enable R8 optimization when compiled on Android.
ServiceLoader.load(
MainDispatcherFactory::class.java,
MainDispatcherFactory::class.java.classLoader
).iterator().asSequence().toList()
}
@Suppress("ConstantConditionIf")
factories.maxByOrNull { it.loadPriority }?.tryCreateDispatcher(factories)
?: createMissingDispatcher()
} catch (e: Throwable) {
// Service loader can throw an exception as well
createMissingDispatcher(e)
}
}
}
可以看到Dispatchers.Main就是单例对象MainDispatcherLoader.loadMainDispatcher()方法的返回值,该方法会通过MainDispatcherFactory去创建一个MainCoroutineDispatcher对象。因此Dispatchers.Main属于MainCoroutineDispatcher类型。MainDispatcherFactory是一个抽象接口,它的实现类是AndroidDispatcherFactory,如下:
internal class AndroidDispatcherFactory : MainDispatcherFactory {
override fun createDispatcher(allFactories: List<MainDispatcherFactory>): MainCoroutineDispatcher {
val mainLooper = Looper.getMainLooper() ?: throw IllegalStateException("The main looper is not available")
return HandlerContext(mainLooper.asHandler(async = true))
}
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
}
很明显这里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的主要源码如下:
// HandlerDispatcher.kt
internal class HandlerContext private constructor(
private val handler: Handler,
private val name: String?,
private val invokeImmediately: Boolean
) : HandlerDispatcher(), Delay {
constructor(
handler: Handler,
name: String? = null
) : this(handler, name, false)
@Volatile
private var _immediate: HandlerContext? = if (invokeImmediately) this else null
override val immediate: HandlerContext = _immediate ?:
HandlerContext(handler, name, true).also { _immediate = it }
override f