You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android项目Dagger 2注入ViewModelFactory报错:lateinit属性未初始化

Fixing Dagger 2 ViewModelFactory Injection in Fragment (Version 2.15)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:26:03