gpt4 book ai didi

android - Dagger 2 无法从子组件注入(inject)

转载 作者:太空宇宙 更新时间:2023-11-03 10:35:07 26 4
gpt4 key购买 nike

我知道通常使用 Kotlin 应该没什么区别,但我遇到过奇怪的情况,其中 @Named限定符在 Kotlin 中需要一个作用域。

我有一个 ViewHolderFactory允许我创建 View 类型的简单映射的类 -> View 持有者类:

@Singleton
class ViewHolderFactoryImpl @Inject constructor(
private val viewHolderComponentProvider: Provider<ViewHolderSubcomponent.Builder>
): ViewHolderFactory(mapOf(
R.layout.view_error to ErrorViewHolder::class.java,
R.layout.view_soft_error to SoftErrorViewHolder::class.java,
R.layout.view_empty to EmptyViewHolder::class.java,
R.layout.view_loading to LoadingViewHolder::class.java,
R.layout.item_got_it to GotItViewHolder::class.java)) {

override fun createViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val viewHolder = super.createViewHolder(parent, viewType)
if (viewHolder is Injectable) {
viewHolderComponentProvider.get()
.viewHolder(viewHolder)
.build()
.inject(viewHolder)
}
return viewHolder
}
}

ViewHolderSubcomponent 定义如下,目标是能够为每个 View 持有者创建一个子组件并注入(inject)一些东西:

@ViewHolderScope
@Subcomponent(modules = [ViewHolderModule::class])
interface ViewHolderSubcomponent {

fun inject(viewHolder: RecyclerView.ViewHolder)

fun viewHolder(): RecyclerView.ViewHolder

@Subcomponent.Builder
interface Builder {
@BindsInstance
fun viewHolder(viewHolder: RecyclerView.ViewHolder): Builder
fun build(): ViewHolderSubcomponent
}
}

ViewHolderModule 定义为:

@Module
class ViewHolderModule {
@Provides @ViewHolderScope
fun provideSectionTitleViewHolder(viewHolder: RecyclerView.ViewHolder): SectionTitleViewHolder =
SectionTitleViewHolder(viewHolder.itemView)
}

当我运行应用程序时,我发现注入(inject)不起作用,我的 @Inject lateinit var值为空。查看生成的代码我可以明白为什么:

@Override
public void inject(RecyclerView.ViewHolder viewHolder) {
MembersInjectors.<RecyclerView.ViewHolder>noOp().injectMembers(viewHolder);
}

没有 MembersInjectors<RecyclerView.ViewHolder>为此子组件创建。我不知道如何让它工作。我知道我应该能够注入(inject)不是由 Dagger 创建的对象,我只是不太清楚我在这里遗漏了什么。

哦,如果有帮助的话,我确实确保包含了 ViewHolderSubcomponent在我的 AppModule subcomponents 的列表

最佳答案

inject(viewHolder: RecyclerView.ViewHolder) 将始终是空操作,因为框架类(或本例中的大多数库)没有任何 @Inject 带注释的字段。 Dagger 只会为您的 inject(MyClass instance) 方法中指定的类生成代码,不会为其任何子类型生成代码。

因此,如果您有一个 ErrorViewHolder : RecyclerView.ViewHolder,那么您必须使用一个具有 inject(ErrorViewHolder instance) 方法的组件来生成代码以注入(inject) ErrorViewHolder.
澄清一下,因为它是生成的代码——而不是运行时的动态反射——调用 inject(viewHolder: RecyclerView.ViewHolder) 就像你对 viewHolder : ErrorViewHolder 所做的那样仍然会尝试为 RecyclerView.ViewHolder 注入(inject)字段,而不是 ErrorViewHolder。如前所述,RecyclerView.ViewHolder 将始终是空操作。

您将不得不对您的设置进行相当多的修改,以便您可以提供一个可以注入(inject)特定查看器的特定子组件,您不能为不同类型使用一个“通用”组件。您可以在 RecyclerView.ViewHolderErrorViewHolder 之间创建一个基类,但话又说回来,您只能注入(inject)声明的字段(和 @Inject 注释)在你的基类中,而不是特定的 child 。

关于android - Dagger 2 无法从子组件注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47785973/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com