Kotlin Multiplatform: IllegalStateException: должен быть основным потоком
я использую
Koin 3.0.0-alpha-4
версия и когда я пытаюсь использовать внедренный класс
koin
, то выдает исключение для стороны iOS:
KotlinException=kotlin.IllegalStateException: Must be main thread, KotlinExceptionOrigin
У меня есть одноэлементный класс, в котором я инициализирую объекты, используя такой коин:
@ThreadLocal
object ObjectFactory : KoinComponent{
val appStateRepository: AppStateRepository by inject()
val appStateRepositoryDemo = AppStateRepository()
}
если я использую
appStateRepository
внутри фонового потока (
Dispatchers.Default
), который вводится коином, затем генерирует исключение.
IllegalStateException: Must be main thread
, но если я использую appStateRepositoryDemo, он отлично работает
Вот метод, который я вызываю из 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
1 ответ
Koin на Kotlin/Native требует внедрения в основной поток, чтобы избежать зависания состояния Koin. В результате вы не можете выполнять инъекцию напрямую из фонового потока.
Добавление специального метода инъекции, который позволил бы вам выполнять инъекцию путем переключения на основной поток, предназначалось для добавления в Koin, но я почти уверен, что он никогда не заканчивался в коде. В первую очередь потому, что это очень редко кому-то нужно.
Так что в любом случае вы не можете этого сделать с Коином. Вы можете попробовать Kodein, но я написал реализацию Koin для throw именно потому, что прикосновение к Koin из другого потока заморозит все внутри него, а это может быть не то, что вы собираетесь делать.
Я знаю, что никто не любит неответы, но почему
ObjectFactory
@ThreadLocal
? Я предполагаю сохранить его изменяемым, но если
appStateRepository
это сингл, он все равно был бы заморожен.