【问题标题】:Kotlin Multiplatform: IllegalStateException: Must be main threadKotlin Multiplatform:IllegalStateException:必须是主线程
【发布时间】:2021-04-24 10:31:00
【问题描述】:

我正在使用Koin 3.0.0-alpha-4 version,当我尝试使用koin 注入的类时,它会为iOS 端抛出异常: KotlinException=kotlin.IllegalStateException: Must be main thread, KotlinExceptionOrigin 我有一个单例类,我正在使用像这样的 koin 初始化对象:

@ThreadLocal
object ObjectFactory : KoinComponent{
  val appStateRepository: AppStateRepository by inject()
  val appStateRepositoryDemo =  AppStateRepository()
}

如果我在后台线程 (Dispatchers.Default) 中使用appStateRepository,它是由 koin 注入的,那么它会抛出异常 IllegalStateException: Must be main thread,但如果我使用 appStateRepositoryDe​​mo,它就可以正常工作

这是我从 iOS 调用以注入模块的方法

fun initKoinIos(
  userDefaults: NSUserDefaults,
  doOnStartup: () -> Unit
): KoinApplication = initKoin {
  module {
    ...
    single { doOnStartup }
  }
}
fun initKoin(appDeclaration: KoinAppDeclaration = {}) = startKoin {
  appDeclaration()
  modules(
    platformModule,
    networkModule,
    useCaseModules,
    repositoryModule,
    commonUtils,
  )
}

用法如下:

fun testRepoAccess() {
     ObjFactory.appStateRepository.test() // Ok, here we are in main thread

     CoroutineScope(Dispatchers.Default).launch {
       ObjFactory.appStateRepositoryDemo.test() //  Ok
       ObjFactory.appStateRepository.test() // Not Ok, throws exception (Must be main thread)
     }
}

预期行为 它应该适用于 iOS,就像它适用于 Android 一样

Koin 3.0.0-alpha-4

附加模块定义

Coroutines 1.4.2-native-mt

更新

我使用了错误的 Koin 库名称,现在我正在使用:

io.insert-koin:koin-core:3.0.1

现在我有另一个例外:

  kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared org.koin.core.context.GlobalContext.KoinInstanceHolder@1c02ca8 from other thread

【问题讨论】:

    标签: kotlin kotlin-coroutines koin kotlin-native kotlin-multiplatform-mobile


    【解决方案1】:

    Kotlin/Native 上的 Koin 需要在主线程上注入,以避免冻结 Koin 状态。因此,您实际上不能直接从后台线程注入。

    添加一个允许您通过切换到主线程进行注入的特殊注入方法是为了添加到 Koin 中,但我很确定这从未在代码中结束。主要是因为很少有人需要它。

    所以,无论如何,你不能用 Koin 做到这一点。你可以试试 Kodein,但我写 Koin 的实现就是为了 throw,因为从另一个线程接触 Koin 会冻结它里面的所有东西,这可能不是你打算做的。

    我知道没有人喜欢不回答,但为什么是ObjectFactory @ThreadLocal?我假设让它保持可变,但如果 appStateRepository 是一个单一的,它无论如何都会被冻结。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多