VIPER架构下Dagger2无法注入Interactor至Presenter的问题
你遇到的lateinit property interactor has not been initialized错误,核心是Dagger2没有机会为Presenter实例注入Interactor依赖,我们一步步拆解问题并给出解决方案:
问题根源分析
手动实例化Presenter跳过Dagger注入流程
在你的ActivityModule里,你通过new MainPresenter()手动创建了Presenter实例:@Provides @PerActivity MainPresenter provideMainPresenter() { return new MainPresenter(); }Dagger2只会为它自己创建的实例处理依赖注入(包括字段注入),手动new出来的对象,Dagger不会解析其中的
@Inject字段,导致interactor始终处于未初始化状态。MainInteractor缺少@Inject构造器
就算Dagger想注入Interactor,它也不知道如何创建MainInteractor的实例——这个类没有标注@Inject构造器,Dagger无法自动提供它的实例。字段注入的潜在风险
你用lateinit var interactor : MainInteractor的字段注入方式,本身就容易出现未初始化错误,也不符合Dagger推荐的构造器注入规范(构造器注入能在对象创建时就保证依赖齐全)。
分步解决方案
1. 给MainInteractor添加@Inject构造器
让Dagger能够自动创建Interactor实例:
class MainInteractor @Inject constructor(): BaseInteractor() { fun doSomething() { Log.e("Hello ", "World!") } }
2. 移除ActivityModule中手动提供Presenter的方法
你的MainPresenter已经有@Inject构造器,Dagger会自动负责创建它的实例,不需要手动提供:
@Module public class ActivityModule { private final BaseActivity mActivity; public ActivityModule(BaseActivity activity) { mActivity = activity; } @Provides @PerActivity BaseActivity activity() { return mActivity; } // 删除下面这个手动创建Presenter的方法 // @Provides @PerActivity // MainPresenter provideMainPresenter() { // return new MainPresenter(); // } }
3. 优化Presenter的注入方式(可选但推荐)
把Interactor改为构造器注入,彻底避免lateinit带来的风险:
class MainPresenter @Inject constructor( private val interactor: MainInteractor ): BasePresenter<MainView.View, MainInteractor>(), MainView.InteractorOutput { override fun onCreate() { interactor.doSomething() } }
如果坚持用字段注入,只要完成前两步,Dagger会自动为@Inject lateinit var interactor注入实例。
验证逻辑
现在当MainActivity中的presenter被Dagger注入时:
- Dagger先创建
MainInteractor实例(因为它有@Inject构造器) - 再用这个Interactor实例创建
MainPresenter(构造器注入场景),或者创建Presenter后注入interactor字段 - 调用
presenter.onCreate()时,interactor已经被正确初始化,不会再报错
内容的提问来源于stack exchange,提问作者Pablo Garcia

