Recently I had problems with a ViewModelProvider.Factory due to it was not loading all ViewModels of the project.
I have Activities and fragments. The activity ones are loaded without any problem, however I've tried to encapsulate FragmentViewModels inside the module where I'm creating the Fragment.
a bit of code:
@Module(includes = [
... ,... ,...
])
class UIModule {
@Singleton
@Provides
fun provideViewModelFactory(viewModels: MutableMap<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>)
: ViewModelProvider.Factory {
return object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return requireNotNull(viewModels[modelClass]).get() as T
}
}
}
}
Activity Builder
@Module
abstract class MainActivityBuilder {
....
@ActivityScope
@ContributesAndroidInjector(modules [XXXFragmentModule::class])
abstract fun bindBottomNavigationActivity(): BottomNavigationActivity
}
so this is the XXXFragmentModule
@Module(includes = [ActividadesFragmentModule.ViewModule::class])
abstract class ActividadesFragmentModule {
....
@ContributesAndroidInjector
internal abstract fun contributeSuggestedFragment(): SuggestedFragment
@Module
abstract class ViewModule {
@Binds
@IntoMap
@ViewModelKey(SuggestedViewModel::class)
internal abstract fun bindSuggestedViewModel(viewModel: SuggestedViewModel): ViewModel
}
}
this does not work, the viewModels of the first block of code does only have the ViewModels of the activities, it does not add this last ViewModel. However if the @Module(includes = [ActividadesFragmentModule.ViewModule::class]) is done in ActivityBuilder it does work perfeclty
@Module(includes = [ActividadesFragmentModule.ViewModule::class])
abstract class MainActivityBuilder
does someone know what I am doing wrong?
You need to remove the scope from your ViewModelProvider.Factory
@Singleton
will never ever get anything from your Activity or Fragment scope. By removing the scope you create a new factory within every component—where it can collect the additional bindings that you added in those lower scopes.
The factory itself is pretty lightweight so there should be no issues if it remains unscoped and gets recreated. @Reusable
"scope" should work as well.