为何Dagger2注入同一对象却生成两个不同实例?Presenter实例不一致致数据丢失
嘿,这个问题我之前踩过类似的坑,核心原因大概率是Dagger2的作用域配置不到位,或者你的Adapter没有正确关联到Fragment的依赖组件,导致每次注入都生成全新的Presenter实例,自然会出现数据丢失的情况。咱们一步步来解决:
一、先排查核心问题:作用域缺失
Dagger2默认是无作用域的,也就是说如果不给依赖指定作用域,每次调用注入都会生成新实例。你的ArticleListFragmentModule和Presenter都没加Fragment级的作用域,这是最可能的原因。
1. 定义Fragment级作用域注解
先创建一个自定义的作用域,用来标记属于Fragment生命周期内的依赖:
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface FragmentScoped {}
2. 给Module和Presenter添加作用域
修改你的ArticleListFragmentModule,加上@FragmentScoped注解,同时给提供Presenter的方法也加上该作用域:
@Module @FragmentScoped public class ArticleListFragmentModule { @Provides @FragmentScoped ArticlesContract.Presenter provideArticlesPresenter(ArticlesPresenter presenter) { return presenter; } }
如果你的ArticlesPresenter是通过构造函数注入的,记得给它的构造函数加@Inject和@FragmentScoped,确保Dagger在Fragment作用域内复用实例:
@FragmentScoped public class ArticlesPresenter implements ArticlesContract.Presenter { @Inject public ArticlesPresenter() { // 你的构造逻辑 } }
3. 给Fragment Component添加作用域
对应的Component也要加上@FragmentScoped,并且暴露Presenter给Adapter使用:
@FragmentScoped @Component(modules = ArticleListFragmentModule.class) public interface ArticleListFragmentComponent { void inject(ArticleListFragment fragment); // 暴露Presenter,让Adapter可以获取到同一个实例 ArticlesContract.Presenter getArticlesPresenter(); }
二、确保Adapter获取到Fragment的Presenter实例
Adapter不能自己单独创建Component或者用全局Component来注入Presenter,必须和Fragment共享同一个Component实例:
方案1:直接传递Presenter给Adapter
最简单的方式就是在Fragment初始化Adapter的时候,把已注入的mPresenter传进去:
// 在ArticleListFragment的onViewCreated里 mAdapter = new ArticleAdapter(mPresenter); recyclerView.setAdapter(mAdapter);
方案2:通过Fragment的Component注入Adapter
如果Adapter需要依赖注入多个对象,可以在Component里添加注入Adapter的方法,然后在Fragment里完成注入:
// 在ArticleListFragmentComponent里添加 void inject(ArticleAdapter adapter); // 在Fragment里初始化Adapter时 mAdapter = new ArticleAdapter(); // 获取Fragment的Component并注入Adapter getComponent().inject(mAdapter);
三、验证效果
做完以上配置后,Fragment和Adapter里的ArticlesContract.Presenter就会是同一个实例了——因为它们都属于同一个Fragment作用域,Dagger会自动复用这个实例,不会再生成新的对象,数据也就不会丢失了。
内容的提问来源于stack exchange,提问作者LWY

