Android 使用Dagger 2注入ViewModel并试图理解@Binds为什么不';当@Provides起作用时,它就不起作用了
我正在尝试注入ViewModelProvider.Factory,但我无法理解为什么不能使用@Binds注释 此注释似乎有效:Android 使用Dagger 2注入ViewModel并试图理解@Binds为什么不';当@Provides起作用时,它就不起作用了,android,dependency-injection,dagger-2,Android,Dependency Injection,Dagger 2,我正在尝试注入ViewModelProvider.Factory,但我无法理解为什么不能使用@Binds注释 此注释似乎有效: @Binds abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory); 结合以下注释,项目将编译: @Provides @IntoMap @ViewModelKey(MyViewModel.class) static ViewModel MyV
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory);
结合以下注释,项目将编译:
@Provides
@IntoMap
@ViewModelKey(MyViewModel.class)
static ViewModel MyViewModel(){
return new MyViewModel();
}
但是,如果将上述代码替换为以下代码:
@Binds
@IntoMap
@ViewModelKey(MyViewModel.class)
abstract ViewModel bindMyViewModel(MyViewModel viewModel);
我突然收到以下错误消息:
…如果没有@Inject构造函数或
@提供带注释的方法
有人能解释为什么第一种情况有效而第二种情况无效吗?正如我所理解的@Binds,它应该创建一个返回类型的类,该类是作为参数传递的具体实现。如注释中所述,如果希望Dagger调用它,则需要使用@Inject
注释MyViewModel构造函数。正如您所提到的,这意味着JSR-330将@Inject
定义为:
- 要标记DI系统应调用以获取实例的构造函数
- 标记DI系统在创建后和现有实例上应填充的字段,以及
- 标记要在创建/注入时调用的方法,从DI系统填充其方法参数
这里要特别清楚的是,Dagger的行为: 使用
@Inject
注释Dagger应用于创建类实例的构造函数。当请求新实例时,Dagger将获得所需的参数值并调用此构造函数
…相矛盾,因为公共无参数构造函数没有资格被调用:
@Inject
对于公共、无参数构造函数是可选的,但不存在其他构造函数。这使注入器能够调用默认构造函数
关于这一偏差的讨论在和中。总之,额外的清晰性被认为是有用的(特别是考虑到您可能意外地使用默认构造函数注入的对象的数量),添加
@inject
的额外成本被确定为不太麻烦,它避免了子类是否符合注入条件的模糊性,而无需检查@Inject
字段的整个类层次结构。您需要使用@Inject
注释来注释MyViewModel的构造函数。谢谢!你能解释一下为什么它有效吗?我并没有试图向构造函数中注入任何东西,构造函数是空的。那么@Inject在这种情况下的功能是什么呢?它只是告诉dagger应该使用这个构造函数来创建想要的实例。对于注释来说,这似乎是一个奇怪的选择。就好像@Inject至少有两个用途。