Почему Dagger2 вводит один и тот же объект, но с двумя разными экземплярами? - PullRequest
0 голосов
/ 07 мая 2018

ArticlesContract.Presenter - это новый экземпляр в Adapter, который отличается от 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: @Binds & @ ContributesAndroidInjector

1 Ответ

0 голосов
/ 08 мая 2018

Это потому, что у вас нет области действия и управления этой областью. Вам нужно создать прицел самостоятельно или использовать уже предоставленный кинжалом. Здесь, поскольку это ведущий, я думаю, это может быть Reusable область действия или Singleton. Однако Singleton оказывает влияние на производительность, что может быть нежелательным.

Следующим важным моментом является то, что вам нужно понимать, что, хотя экземпляр компонента одинаков, предоставляемая привязка будет такой же (исключая случай области действия Reusable). Другими словами, области предоставляют способ сказать кинжалу - «пока этот компонент жив и его область действия - X, тогда все экземпляры, ограниченные X, будут одинаковыми». Вот что я имею в виду в коде:

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

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

Я не знаю, как вы настроили свой компонент, но вам нужно будет также пометить его с помощью PresenterScope. Теперь нужно просто убедиться, что при вводе ArticleListFragment и ArticlesAdapter вы будете использовать один и тот же экземпляр компонента. Если вы перестроите компонент, то экземпляр презентатора будет другим.

Помните, что Reusable немного отличается, но он должен здесь соответствовать вашим потребностям, поскольку докладчик не должен держать состояние.

Надеюсь, это поможет

...