当前位置: 首页 > 知识库问答 >
问题:

无法使用Dagger2将对象注入ViewModel类

濮君植
2023-03-14

我学习了Dagger2,并尝试使用MVVM制作应用程序。我根据方案创建了Dagger类(模块、组件、BaseApplication),但当我尝试将QuotableAPI对象注入ViewModel时,Dagger不会生成DaggerAppComponent类(在ViewModel构造函数中没有QuotableAPI生成)。

报价视图模型

public class QuotesViewModel extends ViewModel {

    private static final String TAG = "QuotesViewModel:";
    private QuotableAPI quotableApi;


    @Inject
    public QuotesViewModel(QuotableAPI quotableAPI) {
        this.quotableApi = quotableAPI;

        Log.d(TAG, "QuotesViewModel created...");
    }
}

应用程序模块

@Module
public class AppModule {

    @Singleton
    @Provides
    static Retrofit provideRetrofitInstance(){
        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    @Singleton
    @Provides
    static QuotableAPI provideQuotableApi(Retrofit retrofit){
        return retrofit.create(QuotableAPI.class);
    }
}

应用组件

@Component(
        modules = {
                AndroidSupportInjectionModule.class,
                ActivityBuildersModule.class,
                AppModule.class,
                ViewModelFactoryModule.class
        }
)
public interface AppComponent extends AndroidInjector<BaseApplication> {

        @Component.Builder
        interface Builder{

                @BindsInstance
                Builder application(Application application);

                AppComponent build();
        }

}

基础应用

public class BaseApplication extends DaggerApplication {
    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerAppComponent.builder().application(this).build();
    }
}

ViewModelFactory

public class ViewModelFactory implements ViewModelProvider.Factory {

    private static final String TAG = "ViewModelProviderFactor";

    private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;

    @Inject
    public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
        this.creators = creators;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        Provider<? extends ViewModel> creator = creators.get(modelClass);
        if (creator == null) { // if the viewmodel has not been created

            // loop through the allowable keys (aka allowed classes with the @ViewModelKey)
            for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {

                // if it's allowed, set the Provider<ViewModel>
                if (modelClass.isAssignableFrom(entry.getKey())) {
                    creator = entry.getValue();
                    break;
                }
            }
        }

        // if this is not one of the allowed keys, throw exception
        if (creator == null) {
            throw new IllegalArgumentException("unknown model class " + modelClass);
        }

        // return the Provider
        try {
            return (T) creator.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

ViewModelFactoryModule

@Module
public abstract class ViewModelFactoryModule {

    @Binds
    public abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory);
}

ViewModelKey

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
public @interface ViewModelKey {
    Class<? extends ViewModel> value();
}

ViewModelModule

@Module
abstract class ViewModelModule {

    @Binds
    @IntoMap
    @ViewModelKey(QuotesViewModel.class)
    public abstract ViewModel bindQuotesViewModel(QuotesViewModel viewModel);
}

和我的依赖项:

implementation 'com.google.dagger:dagger:2.35.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.24'
implementation 'com.google.dagger:dagger-android:2.35.1'
implementation 'com.google.dagger:dagger-android-support:2.24'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.24'

在QuotesViewModel构造函数中没有任何内容,一切都很好,但当我添加任何参数时,我得到了以下错误:

C:\Users\ceran\Desktop\Projekty\Android\BestQuotesApp-dagger\app\src\main\java\com\example\bestquotesapp\di\AppComponent.java:21: error: [Dagger/IncompatiblyScopedBindings] com.example.bestquotesapp.di.AppComponent (unscoped) may not reference scoped bindings:
public interface AppComponent extends AndroidInjector<BaseApplication> {
       ^
      @Singleton @Provides com.example.bestquotesapp.network.QuotableAPI com.example.bestquotesapp.di.AppModule.provideQuotableApi(retrofit2.Retrofit)
      @Singleton @Provides retrofit2.Retrofit com.example.bestquotesapp.di.AppModule.provideRetrofitInstance()

和其他错误,当我再次重建项目时:

C:\Users\ceran\Desktop\Projekty\Android\BestQuotesApp-dagger\app\src\main\java\com\example\bestquotesapp\BaseApplication.java:7: error: cannot find symbol
import com.example.bestquotesapp.di.DaggerAppComponent;
                                   ^
  symbol:   class DaggerAppComponent
  location: package com.example.bestquotesapp.di

共有1个答案

乐正浩博
2023-03-14

QuotableAPI是您的改造路由的接口吗?如果是,您不能提供这样的接口。一种选择是创建一个QuotableAPIClient类来注入改造实例。

public class QuotableAPIClient {

  private QuotableAPI quotableApi;

  @Inject
  public QuotableAPIClient(Retrofit retrofit) {
    quotableApi = retrofit.create(QuotableAPI.class);
  }

}

然后将该客户端注入到您的QuotesViewModel中

public class QuotesViewModel extends ViewModel {

    private static final String TAG = "QuotesViewModel:";
    private QuotableAPIClient quotableApiClient;


    @Inject
    public QuotesViewModel(QuotableAPIClient quotableApiClient) {
        this.quotableApiClient = quotableApiClient;

        Log.d(TAG, "QuotesViewModel created...");
    }
}
 类似资料:
  • 我刚开始使用Dagger并尝试使用dagger2进行DI,但看起来它给我的活动注入了一个空演示器。下面是我的代码。 公共类TasksActivity扩展AppCompatActivity{

  • 嗨,当我尝试在下面的类中注入Doa接口时,我正在使用mvvm和dagger2 我的接口类

  • 我正在尝试使用带有多绑定的Dagger2创建我的ViewModel的依赖注入,但我收到了这个错误,我无法使其工作,我尝试了几个答案(如下),但没有一个对我有帮助。 这是我收到的错误: 这是我的密码 此外,以下是我的应用程序依赖项版本: 我知道这个问题有几个问题,但我试了几个,没有一个对我有效。 以下是我尝试阅读和检查的解决方案链接: https://github.com/android/archi

  • 我只是从喷气背包和剑柄开始。但是当我注入到ViewModel中时,我遇到了一些问题。 我得到的错误: 我可以在活动中注入所有细节,但不能在ViewModel中注入。我已经尝试了所有我能找到的解决办法。 我的gradle文件: 项目根级别: 模块级: 我的申请文件 我的模块文件: 项目是具有可组合屏幕的单个活动,因此主要活动: 视图模型: 我尝试过的事情: 改为ViewModelComponent而

  • 我有很多Android ViewModel类,它们往往有很多依赖项(大多数是Room中的DAO,每个SQLite表一个)。有些依赖项超过10个。 这很好,但Inject构造函数充满了参数,并且只包含样板代码,用于从构造函数参数设置注入的成员。 我想切换到“常规”注入成员,使用注释单独标识,就像其他(哑)类一样。 这对于与Android相关的类(尽管ViewModel被宣传为非Android依赖,例

  • 我正在使用匕首2,我有一个定义如下的: 这是FYViewModel的: 但是,变量始终为空。 如何使用匕首2将Repositroy注入我的ViewModel?