Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/182.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用Dagger 2注入ViewModel并试图理解@Binds为什么不';当@Provides起作用时,它就不起作用了_Android_Dependency Injection_Dagger 2 - Fatal编程技术网

Android 使用Dagger 2注入ViewModel并试图理解@Binds为什么不';当@Provides起作用时,它就不起作用了

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

我正在尝试注入ViewModelProvider.Factory,但我无法理解为什么不能使用@Binds注释

此注释似乎有效:

@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至少有两个用途。