Android中Dagger2注入接口与实现类时报抽象Module含实例@Provides方法错误如何解决
错误触发原因
Dagger2有明确规则:若@Module修饰的类是抽象类,类内部的依赖提供方法只能是两种形式:
- 用
@Binds修饰的抽象方法(仅用于接口和实现类的绑定场景) - 用
@Provides修饰的静态方法
你当前的PersonUsecaseModule是抽象类,但内部3个@Provides方法均为普通实例方法,Dagger无法实例化抽象类来调用实例方法生成依赖,因此抛出对应报错。
另外你还存在两个配置遗漏问题:
- 你要注入的
personWidget变量未添加@Inject注解,Dagger不会主动识别该变量需要注入 PersonUsecaseModule没有添加到任何Component的依赖模块列表中,即使解决抽象类的问题也无法生成对应依赖
解决方案
你可以任选以下两种方案修改PersonUsecaseModule:
方案1(改动最小):去掉Module的抽象修饰
直接把PersonUsecaseModule改为普通非抽象类即可,适合快速修复问题:
@Module class PersonUsecaseModule{ // 删除abstract修饰符 @Provides internal fun provideUseCase(useCase: GetPersonUseCaseImpl): PersonUseCase = useCase @Provides internal fun provideMutableLiveData() = MutableLiveData<PersonUseCase.Result>() @Provides internal fun providePersonWidgetImplScreen(widget: PersonWidgetImpl): PersonWidget = widget }
方案2(更符合Dagger规范):保留抽象类,改用@Binds+静态方法
接口绑定场景用@Binds性能更高,不需要生成方法实现,非接口绑定的依赖放到伴生对象加@JvmStatic声明为静态方法:
@Module abstract class PersonUsecaseModule{ // 接口绑定直接用@Binds修饰抽象方法 @Binds abstract fun provideUseCase(useCase: GetPersonUseCaseImpl): PersonUseCase @Binds abstract fun providePersonWidgetImplScreen(widget: PersonWidgetImpl): PersonWidget // 非接口绑定的依赖放到伴生对象,加@JvmStatic声明为静态 companion object { @JvmStatic @Provides internal fun provideMutableLiveData() = MutableLiveData<PersonUseCase.Result>() } }
补充配置
1. 给注入变量加@Inject注解
修改MainActivity中的变量声明:
@Inject lateinit var personWidget: PersonWidget
2. 注册PersonUsecaseModule
如果你的相关依赖仅在MainActivity中使用,就修改ActivityModule中的ContributesAndroidInjector注解,把Module绑定到MainActivity的子组件:
@ContributesAndroidInjector(modules = [PersonUsecaseModule::class]) abstract fun contributeMainActivity(): MainActivity
如果是全局通用依赖,就添加到ApplicationComponent的modules列表中:
@Singleton @Component( modules = [ ApplicationModule::class, ActivityModule::class, NetworkModule::class, PersonUsecaseModule::class // 新增这行 ] ) interface ApplicationComponent { // 原有代码保持不变 }
内容的提问来源于stack exchange,提问作者MARSH
相关产品推荐
相关产品推荐

