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

MVVM架构下自定义ViewModelFactory无法创建实例错误(Dagger2)

解决"无法创建CakeViewModel实例"的问题

嘿,我帮你找出了两个关键问题,正是它们导致了这个报错:

问题1:ViewModel Factory中的类型判断逻辑错误

看你的CakeViewModelFactory的create方法,你在判断modelClass.isAssignableFrom(Model.class),但你要创建的实例是CakeViewModel啊!这个判断完全错位了,系统会 fallback 到默认的ViewModel工厂,但你的CakeViewModel只有带参数的构造函数,默认工厂根本无法创建它,直接触发报错。

修改后的CakeViewModelFactory代码:

public class CakeViewModelFactory implements ViewModelProvider.Factory{
    private final Model model;
    private final Application application;

    @Inject
    public CakeViewModelFactory(Model model, Application application) {
        this.model = model;
        this.application = application;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        // 这里要判断的是目标ViewModel类,不是Model!
        if (modelClass.isAssignableFrom(CakeViewModel.class)) {
            return (T) new CakeViewModel(model, application);
        }
        throw new IllegalArgumentException("Unknown ViewModel class");
    }
}

问题2:Activity中初始化ViewModel和Dagger注入的顺序颠倒了

在CakesActivity的onCreate方法里,你先调用了ViewModelProviders.of(this, factory).get(CakeViewModel.class),但这时候factory还没被Dagger注入,还是null!系统只能用默认的AndroidViewModelFactory尝试创建,而你的CakeViewModel没有无参构造函数,直接触发创建失败。

你需要先完成Dagger注入,再获取ViewModel,修改后的onCreate代码:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cakes);
    
    // 第一步:先执行Dagger注入,让factory被初始化
    DaggerCakeComponent.builder()
            .cakeModule(new CakeModule(this))
            .applicationComponent(CakeApplication.get(this).getComponent())
            .build().inject(this);
            
    ButterKnife.bind(this);
    initializeList();
    
    // 第二步:注入完成后,再用初始化好的factory获取ViewModel
    CakeViewModel viewModel = ViewModelProviders.of(this, factory).get(CakeViewModel.class);
    observeViewModel(viewModel);
}

额外小建议

既然你已经引入了RxJava2,其实可以优化Model层的代码,把Retrofit的Call转换成Observable,再结合LiveDataReactiveStreams生成LiveData,这样代码更简洁,也能更好地利用RxJava的线程调度能力:

public LiveData<CakeResponse> getCakeList(){
    return LiveDataReactiveStreams.fromPublisher(
        networkService.getTheCakes() // 先把Retrofit接口改成返回Observable<CakeResponse>
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .toFlowable(BackpressureStrategy.LATEST)
    );
}

按照上面的修改,你的创建实例错误应该就能解决了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:38:44