【问题标题】:Dagger 2 scope issue, define child fragment module. result: binding is not resolved for interfaceDagger 2 范围问题,定义子片段模块。结果:没有为接口解析绑定
【发布时间】:2019-01-24 01:12:06
【问题描述】:

我想使用 Dagger 为带有子片段 (X...Z)FragModule 的 AFragment 组成一个模块。

从 ActivityBindingModule 开始,我定义了一个示例 Activity 的依赖模块

/* ActivityBindingModule.java */
@Module
public abstract class ActivityBindingModule{
    @NonNull
    @ActivityScoped
    @ContributesAndroidInjector(modules = {
            AFragModule.class,
            BFragModule.class
            // ... fragment modules
    })
    abstract MainActivity mainActivity();
}

在 AFragModule 中,我定义了它的子片段依赖模块。

/* AFragModule.java */
@Module
public abstract class AFragModule{
    @NonNull
    @FragmentScoped
    @ContributesAndroidInjector(modules = {
            XFragModule.class,
            YFragModule.class
            // ... child fragment modules
    })
    abstract AFragment providesFragment();
}

在 (X...Z)FragModule 中,我定义了它的依赖对象的提供者方法。

/* XFragModule.java */
@Module
public abstract class XFragModule{
    @FragmentScoped
    @ContributesAndroidInjector
    abstract XFragment providesFragment();

    @ActivityScoped
    @Binds
    abstract XContract.Presenter providesPresenter(XPresenter presenter);
}

我希望 (X...Z)FragModule 模块的范围在 AFragModule 中。并且 (X...Z)FragModules 的 Presenter 在同一个范围内存活,以便在 Presenter 之间进行通信。

XPresenter 实现本身使用构造函数注入器,带有@Singleton 参数(例如数据源)

我在上述范围内收到以下错误:

Cause: binding is not resolved for XContract.Presenter: ProvisionBinding{contributionType=UNIQUE, key=XContract.Presenter, bindingElement=Optional[providesPresenter(XPresenter)], contributingModule=Optional[XFragModule], kind=DELEGATE, nullableType=Optional.empty, wrappedMapKeyAnnotation=Optional.empty, provisionDependencies=[DependencyRequest{kind=INSTANCE, key=XPresenter, requestElement=Optional[presenter], isNullable=false}], injectionSites=[], unresolved=Optional.empty, scope=Optional[@ActivityScoped]}

编辑: 我也想检查一下我对范围的理解: 我“认为”我理解以下内容

@Singleton > @ActivityScope > @FragmentScope

  1. 范围不能依赖于相同或更小的范围 前任。 @ActivityScope 不能依赖于@ActivityScope 或@FragmentScope

  2. 范围可以依赖于任何更大的范围。 前任。 @FragmentScope 可以依赖于@Singleton、@ActivityScope 标记的方法。

【问题讨论】:

    标签: android dagger-2


    【解决方案1】:

    在您的具体情况下,Dagger 似乎找不到 XPresenter 的绑定;您有一个声明 @Binds XContract.PresenterXPresenter,但根据您随意提及的“XPresenter 实现本身”,您可能缺少如下声明:

    @Binds
    abstract XPresenter providesXPresenter(XPresenterImpl presenterImpl);
    

    范围可以依赖于相同的范围:@ActivityScope 中的项目可以依赖于@ActivityScope,但不能依赖于@FragmentScope。如果您尝试依赖来自@ActivityScope 的@FragmentScope 对象(“范围扩大注入”),Dagger 将阻止它并描述您可以找到该注入的组件。

    但是,您也可能会遇到@FragmentScope 组件不能包含其他@FragmentScope 组件的问题,这是一个问题,因为@ContributesAndroidInjector 必须创建一个新的子组件,该子组件采用方法上列出的范围和模块。您需要调整您选择的范围注释,例如创建和使用@ParentFragmentScope 和@ChildFragmentScope。这也很重要,因为您的 @ChildFragmentScope Fragment XFragment 可以注入共享 XFragment 的子组件实例、AFragment 的子组件实例、MainActivity 的子组件实例或您的根 @Singleton 组件的生命周期的对象。

    当然,您可能希望根据您的用例命名它们,例如@FullScreenFragmentScope 或@TabFragmentScope 或@OptionalFlowFragmentScope;您还可以选择外部范围以保留@FragmentScope,内部范围为@SubFragmentScope 等,如果您有已经使用@FragmentScope 的可重用模块,这可能特别有用。关键在于,使用 @FragmentScope 的可重用模块并不清楚它是跟踪 AFragment 的生命周期还是 XFragment 的生命周期,因此您需要更清楚这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多