为什么Dagger2注入相同的对象但有2个不同的实例?

时间:2018-05-07 00:33:13

标签: android dagger-2

ArticlesContract.PresenterAdapter中的新实例,与ArticleListFragment不同,因此我的数据丢失了!我不知道为什么我有两个不同的实例:

@Module
public class ArticleListFragmentModule {
    @Provides
    ArticlesContract.Presenter provideArticlesPresenter(ArticlesPresenter presenter) {
        return presenter;
    }
}

public class ArticleListFragment extends DaggerFragment implements ArticlesContract.View {
    @Inject
    ArticlesContract.Presenter mPresenter; //one instance
}


public class ArticlesAdapter extends RecyclerView.Adapter<ArticleViewHolder> {
    @Inject
    ArticlesContract.Presenter mPresenter; //another different instance
}

2018-05-16更新:通过以下@Fred回答修复此问题:缺少范围并管理此范围:

@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface ArticlesScope {
}

@Module
public abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = ArticleListFragmentModule.class)
    @ArticleListScope
    abstract ArticleListFragment bindArticleListFragment();
}

@Module
public class ArticleListFragmentModule {
    /**
     * Provide dependency for interface.
     * Interface cannot be annotated with @Inject, otherwise it will cause, error: ArticlesContract.Presenter cannot be provided without an @Provides- or @Produces-annotated method.
     */
    @Provides
    @ArticleListScope
    ArticlesContract.Presenter provideArticlesPresenter(ArticlesPresenter presenter) {
        return presenter;
    }
}

使用@ContributesAndroidInjector确定范围,请参阅Dagger 2 Annotations: @Binds & @ContributesAndroidInjector

1 个答案:

答案 0 :(得分:1)

这是因为您缺少scope并管理此范围。您需要自己创建一个范围或使用dagger提供的范围。因为它是演示者,所以它可以是我猜的Reusable范围或Singleton。但是,Singleton会产生性能影响,可能并不理想。

下一个重要的事情是你需要了解,虽然组件的实例是相同的,但提供的绑定将是相同的(不包括Reusable范围的情况)。换句话说,范围提供了一种告诉匕首的方法 - &#34;当这个组件存活并且它的范围是X时,那么所有用X作为范围的实例将是相同的#34;。这就是我在代码中的意思:

@Scope
@Documented
@Retention(RUNTIME)
public @interface PresenterScope {}

@Module
public class ArticleListFragmentModule {
  @Provides
  @PresenterScope
  ArticlesContract.Presenter provideArticlesPresenter(ArticlesPresenter presenter) {
    return presenter;
  }
}

我不知道您是如何设置组件的,但您也必须使用PresenterScope对其进行注释。现在,只需要确保当您注入ArticleListFragmentArticlesAdapter时,您将使用相同的组件实例。如果重建组件,则演示者的实例将不同。

请记住,Reusable有点不同,但它应该符合您的需求,因为演示者不应该保持状态。

希望这有帮助