Как правильно создать приложение ViewModel с SavedStateHandle в качестве параметра - PullRequest
0 голосов
/ 30 апреля 2020

Я объявляю ViewModel с SavedStateHandle в качестве параметра в модулях koin

  1. в модулях koin
viewModel { (handle: SavedStateHandle) -> CacheProvider(handle) }

viewModel { SomeFragmentUsedViewModel(get()) }
И инициируйте это в Деятельности
lateinit var cacheProvider: CacheProvider

Повторно использовать его в SomeFragment
private val viewModel: SomeFragmentUsedViewModel by inject()

private val cacheProvider: CacheProvider by sharedViewModel()
При переходе в SomeFragment приложение зависало при доступе к обеим ViewModel:
2020-04-30 22:04:04.858 26677-26677/com.ncbportal.sit E/[Koin]: Instance creation error : could not create instance for [Factory:'com.ncb.common.viewmodel.CacheProvider']: org.koin.core.error.NoParameterFoundException: Can't get parameter value #0 from org.koin.core.parameter.DefinitionParameters@a37a822
        org.koin.core.parameter.DefinitionParameters.elementAt(DefinitionParameters.kt:32)
        org.koin.core.parameter.DefinitionParameters.component1(DefinitionParameters.kt:34)
        com.ncbportal.di.ViewModelModuleKt$viewModelModule$1$77.invoke(Unknown Source:11)
        com.ncbportal.di.ViewModelModuleKt$viewModelModule$1$77.invoke(Unknown Source:4)
        org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
        org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
        org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
        org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
        org.koin.core.scope.Scope.get(Scope.kt:181)
        com.ncbportal.di.ViewModelModuleKt$viewModelModule$1$76.invoke(ViewModelModule.kt:117)
        com.ncbportal.di.ViewModelModuleKt$viewModelModule$1$76.invoke(Unknown Source:4)
        org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
        org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
        org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
        org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
        org.koin.core.scope.Scope.get(Scope.kt:181)
        com.ncbportal.deposit.fragment.ApplyTermDepositFragment$$special$$inlined$inject$1.invoke(ComponentCallbackExt.kt:51)
        kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)


2020-04-30 22:04:04.861 26677-26677/com.ncbportal.sit E/[Koin]: Instance creation error : could not create instance for [Factory:'com.ncbportal.deposit.viewmodel.ApplyTermDepositViewModel']: org.koin.core.error.InstanceCreationException: Could not create instance for [Factory:'com.ncb.common.viewmodel.CacheProvider']
        org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:59)
        org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
        org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
        org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
        org.koin.core.scope.Scope.get(Scope.kt:181)
        com.ncbportal.di.ViewModelModuleKt$viewModelModule$1$76.invoke(ViewModelModule.kt:117)
        com.ncbportal.di.ViewModelModuleKt$viewModelModule$1$76.invoke(Unknown Source:4)
        org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:50)
        org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:36)
        org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:87)
        org.koin.core.scope.Scope.resolveInstance(Scope.kt:214)
        org.koin.core.scope.Scope.get(Scope.kt:181)
        com.nextbank.ncbportal.deposit.fragment.ApplyTermDepositFragment$$special$$inlined$inject$1.invoke(ComponentCallbackExt.kt:51)
        kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)

Поиск всех проблем с репозиторием koin кажется не определенным способом создания прикладной ViewModel (CacheProvider в моем case) для доступа ко всем фрагментам и ViewModel.

У кого-нибудь есть подсказки по этому поводу?

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

Кажется, вы пытаетесь передать viewmodel в другую viewmodel? Нехорошо (какой вид приложения будет широко использоваться?). Ваш CacheProvider должен быть чем-то отличным от модели представления (репозиторий кэша всего приложения?).

Я бы посоветовал вам попробовать это следующим образом: Koin sharedViewModel с SavedStateHandle

В конце дня ваш SomeFragmentUsedViewModel должен управлять сохранением / восстановлением состояния, не CacheProvider. Последнее, вероятно, должно быть так называемым: провайдер кэша, без доступа к механизму сохранения / восстановления состояния просмотра.

Несколько важно сказать, что вышеприведенное работает с koin ver 2.1.5.

0 голосов
/ 01 мая 2020

Согласно этой записи , будет новая версия koin, предоставляющая некоторую функцию расширения для облегчения жизни. Следуйте указаниям после добавления этих функций расширения в качестве обходного пути, пока что это работает.

Но основная проблема заключается в том, что я пытаюсь поместить этот общий для приложений CacheProvider в качестве параметра в SomeFragmentUsedViewModel. Это кажется невозможным для инъекций. Таким образом, поток данных должен быть:

  1. в модуле koin
viewModel { (handle: SavedStateHandle) -> CacheProvider(handle) }

viewModel { SomeFragmentUsedViewModel() }

В деятельности
private val cacheProvider: CacheProvider by stateViewModel {
        parametersOf(
            SavedStateHandle()
        )
    }
Повторно использовать его в SomeFragment
private val viewModel: SomeFragmentUsedViewModel by inject()

private val cacheProvider: CacheProvider by stateSharedViewModel()

Подача данных из cacheProvider в viewModel. Таким образом, фрагмент работает как мост между двумя ViewModels.
cacheProvider.data?.let { safeData ->
  viewModel.initDataWith(safeData)

}
...