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

Android开发:Dagger2注入ViewModel报错,需@Provides注解方法

解决Dagger2 ViewModel注入时的Map<Class<ViewModel>, Provider<ViewModel>>缺失问题

这个错误的核心原因很明确:Dagger找不到用来构建Map<Class<? extends ViewModel>, Provider<ViewModel>>的绑定配置——这个Map是Dagger多绑定的核心,用来把各个ViewModel和它们的提供者关联起来,你的代码里肯定漏了关键的绑定步骤。

下面是一步步的修复方案:

1. 定义ViewModel的多绑定Key注解

先创建一个自定义的MapKey注解,用来标识每个ViewModel的类型,Dagger会用它来区分Map里的不同条目:

@MapKey
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
annotation class ViewModelKey(val value: KClass<out ViewModel>)

2. 绑定ViewModel到多绑定Map中

创建一个抽象的Dagger模块,用@Binds + @IntoMap + @ViewModelKey的组合,把每个ViewModel绑定到Map里:

@Module
abstract class ViewModelModule {
    // 替换成你自己的ViewModel类
    @Binds
    @IntoMap
    @ViewModelKey(HomeViewModel::class)
    abstract fun bindHomeViewModel(viewModel: HomeViewModel): ViewModel

    // 如果有多个ViewModel,重复上面的绑定逻辑即可
    @Binds
    @IntoMap
    @ViewModelKey(ProfileViewModel::class)
    abstract fun bindProfileViewModel(viewModel: ProfileViewModel): ViewModel
}

注意:你的ViewModel类的构造函数必须加上@Inject注解,否则Dagger无法创建它的实例。

3. 确保Component包含这个模块

把刚才的ViewModelModule添加到你的AppComponent(或者对应的子Component)的modules列表中:

@Singleton
@Component(modules = [AndroidSupportInjectionModule::class, ViewModelModule::class, /* 其他模块 */])
interface AppComponent : AndroidInjector<YourApplication> {
    @Component.Factory
    interface Factory {
        fun create(@BindsInstance application: Application): AppComponent
    }
}

4. 正确实现ViewModelFactory

你需要一个依赖这个Map的ViewModelFactory,并且让Dagger注入它:

class DaggerViewModelFactory @Inject constructor(
    // 这里必须加@JvmSuppressWildcards,否则Kotlin泛型和Dagger的Java泛型会不兼容
    private val viewModels: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        val provider = viewModels[modelClass]
            ?: throw IllegalArgumentException("ViewModel class $modelClass not found in Dagger bindings")
        return provider.get() as T
    }
}

常见的坑要注意

  • 不要忘记给ViewModel的构造函数加@Inject,否则Dagger无法提供它的Provider
  • Map的泛型必须加@JvmSuppressWildcards,Kotlin的泛型通配符和Java处理方式不同,不加会导致Dagger无法识别绑定
  • 确认你的Component确实包含了ViewModelModule,如果是子Component,要确保父Component传递了必要的绑定

内容的提问来源于stack exchange,提问作者Simon Schiller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:10:25