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

Dagger2 ViewModel注入重构报错:缺少@Provides注解方法提供Map依赖

解决Dagger2重构后ViewModel映射无法提供的错误

这个错误我之前重构项目时也踩过坑!本质就是Dagger找不到构建Map<Class<? extends ViewModel>, Provider<ViewModel>>的来源——这个Map是ViewModelFactory用来根据类名创建对应实例的核心依赖,重构时很容易不小心破坏了相关配置。下面是几个最常见的排查和修复方向:

1. 检查ViewModelModule的注解是否完整

重构时最容易遗漏或误改的就是@IntoMap和@ViewModelKey这些关键注解,或者搞错了Module的类型(比如把抽象类改成普通类,反之亦然)。

如果你的ViewModel本身带有@Inject构造函数,用@Binds绑定的Module应该是这样:

@Module
public abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(HomeViewModel.class)
    abstract ViewModel bindHomeViewModel(HomeViewModel viewModel);

    // 其他ViewModel的绑定逻辑同理
}

如果ViewModel需要外部依赖、构造函数没有@Inject,则用@Provides提供实例:

@Module
public class ViewModelModule {
    @Provides
    @IntoMap
    @ViewModelKey(HomeViewModel.class)
    ViewModel provideHomeViewModel(HomeRepository homeRepo) {
        return new HomeViewModel(homeRepo);
    }
}

另外要确认你的自定义@ViewModelKey注解类没有被误删或修改:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewModelKey {
    Class<? extends ViewModel> value();
}

2. 确认AppComponent正确包含了ViewModelModule

重构时如果调整了Component的依赖关系或Module的位置,很可能会把ViewModelModule从Component的modules列表里漏掉。检查你的AppComponent配置:

@Component(modules = {
    AndroidInjectionModule.class,
    ViewModelModule.class, // 必须确保这个Module在这里
    ActivityBindingModule.class,
    // 其他必要的Module
})
public interface AppComponent extends AndroidInjector<MyApp> {
    // ...
}

3. 检查ViewModelFactory的注入配置

这个Map是通过ViewModelFactory的构造函数注入的,要确保Factory的构造函数带有@Inject注解,或者在Module里正确提供它:

public class ViewModelFactory implements ViewModelProvider.Factory {
    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModelCreators;

    // 必须有@Inject,让Dagger自动注入这个Map
    @Inject
    public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModelCreators) {
        this.viewModelCreators = viewModelCreators;
    }

    @Override
    @NonNull
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        Provider<? extends ViewModel> creator = viewModelCreators.get(modelClass);
        if (creator == null) {
            throw new IllegalArgumentException("Unknown ViewModel class: " + modelClass);
        }
        try {
            return (T) creator.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

同时,在需要使用ViewModel的Activity/Fragment里,要确保注入这个Factory,而非手动实例化:

public class HomeActivity extends AppCompatActivity {
    @Inject
    ViewModelFactory viewModelFactory;
    private HomeViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this, viewModelFactory).get(HomeViewModel.class);
    }
}

4. 清理kapt缓存并重建项目

有时候重构后kapt生成的Stub文件(就是报错里提到的tmp/kapt3/stubs目录下的文件)会残留缓存,导致Dagger识别不到最新配置。执行以下操作:

  • 在Android Studio里点击Build -> Clean Project
  • 接着点击Build -> Rebuild Project
  • 或者用命令行执行:./gradlew clean build

以上几步排查下来,基本能解决这个问题。我当时就是重构时不小心把ViewModelModule从AppComponent的modules列表里删掉了,加回去再清理缓存就恢复正常了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:36:53