You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Dagger2注入同一对象却生成两个不同实例?Presenter实例不一致致数据丢失

解决Dagger2中Presenter在Fragment和Adapter实例不一致的问题

嘿,这个问题我之前踩过类似的坑,核心原因大概率是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:44:50