Android Dagger2继承的子组件多绑定
希望在日复一日地研究这个非常感兴趣的主题“继承子组件Android Dagger2继承的子组件多绑定,android,kotlin,dagger-2,dagger,Android,Kotlin,Dagger 2,Dagger,希望在日复一日地研究这个非常感兴趣的主题“继承子组件多绑定”之后,能在这里找到一些帮助,这是该页面中的最后一个主题 根据官方文件: 子组件可以将元素添加到其父组件中绑定的多绑定集合或映射中。发生这种情况时,集合或映射根据其注入的位置而不同。当将其注入在子组件上定义的绑定中时,则具有子组件的mu定义的值或条目ltibindings以及父组件的多绑定定义的绑定。当它被注入父组件上定义的绑定时,它只有在那里定义的值或条目 换句话说,如果父组件具有一个多绑定集或映射,并且子组件具有与该多绑定的绑定,则这
多绑定”
之后,能在这里找到一些帮助,这是该页面中的最后一个主题
根据官方文件:
子组件
可以将元素添加到其父组件中绑定的多绑定
集合或映射中。发生这种情况时,集合或映射根据其注入的位置而不同。当将其注入在子组件
上定义的绑定中时,则具有子组件的mu定义的值或条目ltibindings
以及父组件的多绑定定义的绑定。当它被注入父组件上定义的绑定时,它只有在那里定义的值或条目
换句话说,如果父组件
具有一个多绑定集或映射
,并且子组件
具有与该多绑定的绑定,则这些绑定将链接/添加到父映射中,具体取决于这些绑定在dagger范围内的注入位置(如果有)
问题就在这里。
在Android应用程序中使用dagger version 2.24
,使用Kotlin
。我有一个ApplicationComponent
,使用了新的@Component.Factory
方法。ApplicationComponent安装了AndroidSupportInjunctionModule
我还有一个使用新的@Component.Factory
方法的ActivitySubComponent
,这个方法使用模块注释的subComponents
参数链接到AppComponent。
此ActivitySubComponent通过如下绑定提供了一个ViewModel
@Binds
@IntoMap
@ViewModelKey(MyViewModel::class)
fun provideMyViewModel(impl: MyViewModel): ViewModel
@ViewModelKey
是一个自定义匕首注释
我还有一个像这样实现的ViewModelFactory
@Singleton
class ViewModelFactory @Inject constructor(
private val viewModelsToInject: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T =
viewModelsToInject[modelClass]?.get() as T
}
@Singleton
类ViewModelFactory@Inject构造函数(
私有val viewModelsToInject:映射
):ViewModelProvider.Factory{
重写趣味创建(modelClass:Class):T=
ViewModelsToInjection[modelClass]?.get()作为T
}
普通ViewModelFactory
这里的区别是我在一个AppComponents模块中提供了这个ViewModelFactory。但是ActivitySubComponent中的绑定viewModels没有添加到AppComponent中的ViewModelFactory映射中
换句话说,文档所描述的根本没有发生
如果我将viewModels绑定移动到任何AppComponent模块中,那么所有模块都可以工作
您知道这里会发生什么吗。您正在将您的ViewModelProvider.Factory
范围限定为@Singleton
。这确保了它将被创建并保存在@Singleton
组件中
删除作用域是安全的,因为它不保留任何状态,并且允许在需要时使用正确的绑定集创建工厂。文档是准确的。虽然Dagger的操作方式与生成set/Map MultiBindind时所描述的方式相同,但它的工作方式不同,因为您处于一个困境中
举例说明
假设您有以下模块:
/**
* Binds ViewModelFactory as ViewModelProvider.Factory.
*/
@Module
abstract class ViewModelProviderModule {
@Binds abstract fun bindsViewModelFactory(impl: ViewModelFactory): ViewModelProvider.Factory
}
/**
* For the concept, we bind a factory for an AppViewModel
* in a module that is included directly in the AppComponent.
*/
@Module
abstract class AppModule {
@Binds @IntoMap
@ViewModelKey(AppViewModel::class)
abstract fun bindsAppViewModel(vm: AppViewModel): ViewModel
}
/**
* This module will be included in the Activity Subcomponent.
*/
@Module
abstract class ActivityBindingsModule {
@Binds @IntoMap
@ViewModelKey(MyViewModel::class)
}
/**
* Generate an injector for injecting dependencies that are scoped to MyActivity.
* This will generate a @Subcomponent for MyActivity.
*/
@Module
abstract class MyActivityModule {
@ActivityScoped
@ContributesAndroidInjector(modules = [ActivityBindingsModule::class])
abstract fun myActivity(): MyActivity
}
如果要将ViewModelProvider.Factory
注入到应用程序类中,那么Map
中应该提供什么?因为您是在AppComponent
的范围内注入,所以ViewModelFactory
将只能创建AppViewModel
的实例,而不能创建MyViewModel
since绑定在子组件中定义
如果在MyActivity
中插入ViewModelProvider.Factory
,那么由于我们都在AppComponent
和MyActivitySubcomponent
的范围内,那么新创建的ViewModelFactory
将能够创建AppViewModel
和MyViewModel
的两个实例
这里的问题是ViewModelFactory
被注释为@Singleton
。因此,ViewModelFactory的单个实例被创建并保存在AppComponent
中。由于MainActivityComponent
是AppComponent
的子组件,因此它继承了该Singleton和不会创建包含带有2ViewModel
绑定的映射的新实例
下面是正在发生的事情的顺序:
调用了MyApplication.onCreate()
。您可以创建DaggerAppComponent
DaggerAppComponent
的构造函数中,Dagger构建了一个映射,该映射具有类
到提供者的映射
ViewModelFactory
的依赖项,然后将其保存在组件中ViewModelFactory
的引用,并直接注入它(它不会修改映射)ViewModelFactory
上的@Singleton
注释。这确保Dagger每次需要时都会创建一个ViewModelFactory
的新实例。这样,ViewModelFactory
将收到一个包含这两个绑定的映射ViewModelFactory
上的@Singleton
注释替换为@reusible
。这样,Dagger将尝试重用ViewModelProvider
的实例,而不保证在整个应用程序中使用唯一的实例。如果检查生成的代码,您将注意到不同的ins实例保存在每个AppComponent
和MyActivitySubcomponent
中