android - 没有专用子组件的片段注入
问题描述
我正在尝试使用 android-dagger 从手动定义的子组件中注入一个片段:
@Component(modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
BuilderModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>()
fun someComponent(): SomeComponent
}
@Subcomponent
interface SomeComponent {
fun inject(fragment: SomeFragment)
}
执行失败:
IllegalArgumentException:没有注入器工厂绑定到类“SomeFragment”
但是,如果我创建一个用@ContributesAndroidInjector
它注释的片段绑定,则可以正常执行。该文档指出,所有这些都是创建一个子组件。为什么我不能手动操作?
最小的工作项目可以在 github 上找到: https ://github.com/absimas/fragment-injection
解决方案
@ContributesAndroidInjector
创建一个子组件,是的。文档没有再说什么,但他们没有断言这只会创建一个子组件;它还将它安装到为每个Map<Class, AndroidInjector.Factory>
dagger.android的注入类型提供支持的多重绑定中。
您可以在 Dagger User's Guide的 Android 页面上看到此地图绑定的示例:
@Binds
@IntoMap
@FragmentKey(YourFragment.class)
abstract AndroidInjector.Factory<? extends Fragment>
bindYourFragmentInjectorFactory(YourFragmentSubcomponent.Builder builder);
请注意,这期望您绑定 Builder,而不是 Component:dagger.android 期望您希望从子组件中访问 Fragment 实例,因此绑定是为了AndroidInjector.Factory<? extends Fragment>
DispatchingAndroidInjector可以调用create(Fragment)
它。这被设计为兼容Subcomponent.Builder
,但它确实需要您定义@Subcomponent.Builder
扩展适配器的嵌套接口AndroidInjector.Builder
。请原谅我对 Kotlin 问题的 Java:
/** No need for an explicit inject, because you must extend AndroidInjector. */
@Subcomponent
interface SomeComponent extends AndroidInjector<SomeFragment> {
/**
* This abstract class handles the final create(Fragment) method,
* plus @BindsInstance.
*/
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<SomeFragment> {}
}
编辑:我现在想到您的标题表明您不需要专用的子组件;除了使用手动定义而不是@ContributesAndroidInjector
,如果你想要一个多片段子组件,那么你可能会遇到这个建议的一些麻烦:dagger.android 需要实现AndroidInjector<YourFragment>
,并且由于擦除,你自己不能拥有一个类实现多个AndroidInjector<T>
或AndroidInjector.Builder<T>
接口或抽象类。在这些情况下,您可能需要编写一个手动 AndroidInjector.Factory 实现来调用正确的具体inject
方法。然而,为了创建一个整体的 Fragment 组件,这似乎需要做很多工作,因为最佳实践决定了 dagger.android 的默认值:每个 Fragment 都有一个小而特定的组件。
推荐阅读
- javascript - 从 mysql 检索后在 html 中显示 javascript 数据
- r - 为什么 pivot_wider 要么将单个值读取为重复值,要么创建一个宽而长的小标题(不合并行)?
- c++ - 这是对 reinterpret_cast 未定义行为的使用吗?
- python - 当根据每个国家的数据计算平均值时,如何用变量的平均值替换 NA
- scala - 使用 Slick 插入具有自动递增 ID 的值的通用存储库/DAO 方法缺少隐式
- python - 如何在此算法的部分添加打印功能以打印出所有已进行的迭代?
- python - 如何从文件夹中选择 csv 文件中的列?
- python - selenium 在添加 --headless 选项时给出未知错误
- javascript - jQuery Lazy 不工作——使用 Airtable 和 Vue
- r - 合并数据集后,我丢失了变量的标签。有没有办法从原始数据集中取回它们?