Reputation: 1933
ArticlesContract.Presenter
is a new instance in Adapter
, which is different with ArticleListFragment
, so my data was lost ! I have no idea why I got two different instances:
@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
}
@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;
}
}
Scoping with @ContributesAndroidInjector, refer to Dagger 2 Annotations: @Binds & @ContributesAndroidInjector
Upvotes: 0
Views: 1396
Reputation: 17085
This is because you lack a scope and managing this scope. You need to create a scope yourself or use one provided by dagger already. Here since it's a presenter it can be the Reusable
scope I guess or Singleton
. However, Singleton
has a performance impact that might not be desirable.
The next important thing is that you need to understand that while the component's instance is the same the provided binding will be the same (excluding the case of the Reusable
scope). In other words, scopes provide a way of telling dagger - "while this component is alive and it's scope is X then all instances scoped with X will be the same". Here's what I mean in code:
@Scope
@Documented
@Retention(RUNTIME)
public @interface PresenterScope {}
@Module
public class ArticleListFragmentModule {
@Provides
@PresenterScope
ArticlesContract.Presenter provideArticlesPresenter(ArticlesPresenter presenter) {
return presenter;
}
}
I don't know how you've set up your component, but you'd have to annotate it also with the PresenterScope
. Now, it's just a matter of making sure that when you inject ArticleListFragment
and ArticlesAdapter
you'll be using the same instance of the component. If you rebuild the component than the instance of the presenter will be different.
Remember that Reusable
is a bit different, but it should suit your needs here since the presenter should hold no state.
Hope this helps
Upvotes: 1