Kotlin 多平台:IllegalStateException:必须是主线程

问题描述

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

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

如果我在后台线程 (appStateRepository) 中使用 dispatchers.Default,它是由 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/Native 上的 Koin 需要在主线程上注入,以避免冻结 Koin 状态。因此,您实际上无法直接从后台线程注入。

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

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

我知道没有人喜欢非答案,但为什么 go volatile boolean go; ?我假设让它保持可变,但如果 ObjectFactory 是一个单一的,它无论如何都会被冻结。