Android项目Dagger 2注入ViewModelFactory报错:lateinit属性未初始化
Hey there! Let's troubleshoot why your viewModelFactory isn't initializing in your Fragment. That lateinit property viewModelFactory has not been initialized error is a clear sign Dagger isn't properly injecting dependencies into your Fragment, so let's walk through the most common fixes step by step.
1. Make Sure Your Fragment Triggers Dagger Injection
First off, Dagger won't inject your Fragment unless you explicitly tell it to. Add this code to your Fragment's onAttach method—this is the key step that kicks off injection:
override fun onAttach(context: Context) { AndroidInjection.inject(this) super.onAttach(context) }
Also, double-check that your Dagger Component (like an ActivityComponent or FragmentComponent) includes an injection method for your Fragment:
@FragmentScope @Component(dependencies = [AppComponent::class], modules = [ViewModelModule::class]) interface FragmentComponent { fun inject(YourMainFragment fragment) }
2. Verify Your ViewModelModule Configuration
You mentioned you have a ViewModelModule—let's ensure it's set up to correctly provide ViewModelProvider.Factory and your StationsViewModel. Here's a standard working setup:
First, Create a Custom ViewModelKey Annotation
This helps Dagger map different ViewModel types to their implementations:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @Retention(AnnotationRetention.RUNTIME) @MapKey annotation class ViewModelKey(val value: KClass<out ViewModel>)
Then, Update Your ViewModelModule
Use @Binds (for abstract modules) or @Provides (for concrete modules) to declare your ViewModel and Factory:
@Module abstract class ViewModelModule { // Bind your StationsViewModel to the generic ViewModel type @Binds @IntoMap @ViewModelKey(StationsViewModel::class) abstract fun bindStationsViewModel(viewModel: StationsViewModel): ViewModel // Bind your custom factory to ViewModelProvider.Factory @Binds abstract fun bindViewModelFactory(factory: DaggerViewModelFactory): ViewModelProvider.Factory }
If you prefer using @Provides (for non-abstract modules), here's an alternative:
@Module class ViewModelModule { @Provides fun provideViewModelFactory( viewModelMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>> ): ViewModelProvider.Factory { return DaggerViewModelFactory(viewModelMap) } @Provides @IntoMap @ViewModelKey(StationsViewModel::class) fun provideStationsViewModel( // Inject any dependencies your ViewModel needs here someRepository: SomeRepository ): StationsViewModel { return StationsViewModel(someRepository) } }
Don't Forget the Custom ViewModelFactory
You'll need a concrete factory class that uses Dagger's mapped ViewModels:
class DaggerViewModelFactory( private val viewModelMap: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>> ) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { val provider = viewModelMap[modelClass] ?: viewModelMap.entries.firstOrNull { modelClass.isAssignableFrom(it.key) }?.value ?: throw IllegalArgumentException("Unknown ViewModel class: $modelClass") return provider.get() as T } }
3. Ensure Your Dagger Component Includes the ViewModelModule
Your top-level Component (like AppComponent) or Fragment/Activity Component must include the ViewModelModule so Dagger can access the bindings:
@Singleton @Component(modules = [ViewModelModule::class, AppModule::class]) interface AppComponent { // Expose dependencies to child components if needed fun fragmentComponent(): FragmentComponent.Factory }
4. Check Your StationsViewModel Constructor
Make sure your ViewModel's constructor is annotated with @Inject—this lets Dagger create instances of it:
class StationsViewModel @Inject constructor( private val someRepository: SomeRepository // Add your required dependencies here ) : ViewModel() { // ViewModel logic goes here }
Final Notes
After making these changes, rebuild your project (clean + rebuild to avoid Dagger cache issues) and test again. The lateinit error should disappear once Dagger properly injects the viewModelFactory into your Fragment.
内容的提问来源于stack exchange,提问作者Ana Koridze

