碰到个异常记录下坑
Module with the Main dispatcher is missing. Add dependency providing the Main dispatcher, e.g. ‘kotlinx-coroutines-android’ and ensure it has the same version as 'kotlinx-coroutines-core’
解决办法:
如果你是Debug的版本未混淆代码,抛出这种异常,那应该是你两个协程库的版本不一致导致,所以把两个库的版本改成一样的。
//kotlin 协程
"kotlin-coroutines-core" : "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7",
"kotlin-coroutines-android": "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7",
如果你是Release版本使用了代码混淆,可能你把两个库版本改成一样也没有用,还是会抛异常,需要你在混淆规则文件proguard-rules.pro里面添加一条规则。
# kotlin混淆
-keep class kotlinx.coroutines.android.AndroidDispatcherFactory {*;}
如果只想解决,那你不用继续往下看了,下面我们分析下为什么会出这个异常。
这个异常是在协程MainDispatcherLoader类里面抛出来的
@Suppress("ConstantConditionIf")
private fun createMissingDispatcher(cause: Throwable? = null, errorHint: String? = null) =
if (SUPPORT_MISSING) MissingMainCoroutineDispatcher(cause, errorHint) else
cause?.let { throw it } ?: throwMissingMainDispatcherException()
internal fun throwMissingMainDispatcherException(): Nothing {
throw IllegalStateException(
"Module with the Main dispatcher is missing. " +
"Add dependency providing the Main dispatcher, e.g. 'kotlinx-coroutines-android' " +
"and ensure it has the same version as 'kotlinx-coroutines-core'"
)
}
MainDispatcherLoader类里面的loadMainDispatcher方法,当你调用了Dispatch.Main的时候,最终事件会分发到这,通过ServiceLoader加载MainDispatcherFactory类,MainDispatcherFactory类找不到,就走到了catch里面抛出了createMissingDispatcher()。
没混淆代码的时候能正常加载,混淆之后就找不到类了,其实这也是kotlinx的一问题。点这个看issure
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.maxBy { it.loadPriority }?.tryCreateDispatcher(factories)
?: createMissingDispatcher()
} catch (e: Throwable) {
// Service loader can throw an exception as well
//在这里抛出异常
createMissingDispatcher(e)
}
}