Dagger2注入异常:为继承关系的Fragment注入对应Presenter报错
解决Fragment继承场景下的Dagger Presenter注入问题
兄弟,我太懂你这种继承式组件注入踩坑的痛了!你说的ListWithFilterFragment继承ListFragment、Presenter也跟着继承,还分别搞了Module和Component却注入报错,大概率是Dagger的组件关联、模块提供或者Fragment注入环节出了问题。我给你拆解下常见问题和亲测有效的解决办法:
一、先把Component的继承/依赖关系捋顺
Dagger里组件没法直接用Java接口继承那套逻辑,要复用父Component的依赖,得用**@Subcomponent或者dependencies**属性来关联,这是最容易踩的坑!
示例:父Component(ListComponent)
@Singleton @Component(modules = [ListModule::class]) interface ListComponent { // 声明注入ListFragment的入口方法 fun inject(fragment: ListFragment) // 如果用Subcomponent模式,要暴露子组件的工厂,让父组件能创建它 fun listWithFilterComponentFactory(): ListWithFilterComponent.Factory }
示例:子Component(ListWithFilterComponent)
推荐用Subcomponent模式(能完全复用父Component的所有依赖,不用手动暴露):
@Subcomponent(modules = [ListWithFilterModule::class]) interface ListWithFilterComponent { // 声明注入子Fragment的入口方法 fun inject(fragment: ListWithFilterFragment) // 定义子组件的工厂接口 @Subcomponent.Factory interface Factory { fun create(): ListWithFilterComponent } }
如果非要用dependencies模式(需要父Component手动暴露要复用的依赖):
@Component( modules = [ListWithFilterModule::class], dependencies = [ListComponent::class] ) interface ListWithFilterComponent { fun inject(fragment: ListWithFilterFragment) }
二、检查Presenter的Module提供是否正确
你的ListWithFilterPresenter继承ListPresenter,要确保Module里正确提供子类实例,或者让父类依赖能兼容子类:
示例:父Module(ListModule)
@Module class ListModule { @Provides fun provideListPresenter(): ListPresenter { return ListPresenter() } }
示例:子Module(ListWithFilterModule)
如果要提供子类Presenter,要么单独声明,要么用@Binds更高效地绑定继承关系:
// 用@Binds的话,Module要改成abstract类 @Module abstract class ListWithFilterModule { // 提供子类Presenter实例 @Provides fun provideListWithFilterPresenter(): ListWithFilterPresenter { return ListWithFilterPresenter() } // 绑定子类到父类,让Dagger能自动处理继承依赖 @Binds abstract fun bindListPresenter(presenter: ListWithFilterPresenter): ListPresenter }
三、Fragment中的注入代码要对应正确的Component
两个Fragment的注入逻辑要分开,子类Fragment还要注意注入顺序:
示例:ListFragment的注入
class ListFragment : Fragment() { @Inject lateinit var presenter: ListPresenter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 获取全局的ListComponent实例并注入 (requireActivity().application as MyApp).listComponent.inject(this) } }
示例:ListWithFilterFragment的注入
class ListWithFilterFragment : ListFragment() { @Inject lateinit var presenter: ListWithFilterPresenter override fun onCreate(savedInstanceState: Bundle?) { // 先调用父类onCreate,确保父类Presenter被注入 super.onCreate(savedInstanceState) // 从父Component获取子Component工厂,创建子Component后注入 val listWithFilterComponent = (requireActivity().application as MyApp).listComponent .listWithFilterComponentFactory() .create() listWithFilterComponent.inject(this) } }
四、最后排查几个常见错误点
- 有没有在Component中声明对应的
inject(Fragment)方法?Dagger找不到注入入口就会报错 - 子Component是不是没关联父Component?导致父类Presenter的依赖拿不到
- Module里的
@Provides/@Binds是不是类型不匹配?比如把父类和子类的返回值搞混了 - Fragment是不是拿错了Component实例?比如用父Component去注入子类Presenter,肯定找不到
内容的提问来源于stack exchange,提问作者Saber Solooki
相关产品推荐
相关产品推荐

