首页 > 解决方案 > 错误:[Dagger/DuplicateBindings] com.example.StartRouter 被绑定多次?

问题描述

我有一堂课StartRouter。我想为每个活动提供此类的不同实例,并且只要活动还活着(为此我做了@ActivityScope),它就保持活动状态。

问题是它在我的代码中没有这样做。似乎匕首为每个注释提供了一个实例,在我的情况下,一次用于@ActivityScope. 此范围是自定义匕首范围。

这是我的两个模块(每个活动一个),第一个模块:

@Module
public class SplashModule {

    @Provides
    SplashVMFactory splashVMFactory(StartRouter startRouter){
        return new SplashVMFactory(startRouter);


    @Provides
    StartRouter startRouter(){
        return new StartRouter();
    }

}

第二个模块:

@Module
public class QuestionModule {

    @Provides
    QuestionVMFactory questionVMFactory(StartRouter startRouter){
        return new QuestionVMFactory(startRouter);
    }

    @Provides
    StartRouter startRouter(){
        return new StartRouter();
    }

}

我有这个:

@Module
public abstract class BinderModule {

    @ActivityScope
    @ContributesAndroidInjector(modules = SplashModule.class)
    abstract SplashActivity bindSplashActivity();

    @ActivityScope
    @ContributesAndroidInjector(modules = QuestionModule.class)
    abstract QuestionActivity bindQuestionActivity();

}

我的应用程序组件:

@ApplicationScope
@Component(modules = {AndroidInjectionModule.class,
        BinderModule.class,
        SplashModule.class,
        QuestionModule.class})
public interface AppComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(App app);
        AppComponent build();
    }

    void inject(App app);

}

当我运行这个我得到这个错误:

error: [Dagger/DuplicateBindings] com.example.StartRouter is bound multiple times:
@Provides com.example.StartRouter com.example.QuestionModule.startRouter()
@Provides com.example.StartRouter com.example.SplashModule.startRouter()
com.example.StartRouter is injected at
com.example.LoginModule.loginVMFactory(…, startRouter)
com.example.LoginVMFactory is injected at
com.example.LoginActivity.factory
com.example.LoginActivity is injected at
dagger.android.AndroidInjector.inject(T) [com.example.AppComponent ? com.example.BinderModule_BindLoginActivity.LoginActivitySubcomponent]
It is also requested at:
com.example.QuestionModule.questionVMFactory(…, startRouter)
The following other entry points also depend on it:
dagger.android.AndroidInjector.inject(T) [com.example.AppComponent ? com.example.BinderModule_BindQuestionActivity.QuestionActivitySubcomponent]

(从我的错误中可以看出,除了两个示例之外,其他模块中还提供了 StartRouter)。

我想,如果我理解正确的话,使用@ActivityScopein BinderModulewith@ContributesAndroidInjector会为每个活动创建不同的组件,只要活动本身还活着,但我似乎理解错了吗?

如果我通过使用和提供 1 个模块来区分StartRouter我的 s 中的不同之处,那么这将通过提供不同的实例来解决问题吗?但这对我的问题没有帮助。简而言之,我的问题是,我无法提供与活动本身一样长的实例(每个活动 1 个)。关于我如何做到这一点的任何建议?@module@named@namedStartRouter@ActivityScoped StartRouter

标签: androiddagger-2dagger

解决方案


您的设置很好,但是因为您添加了两个模块(都绑定StartRouter)到AppComponent,因此您多次绑定它的错误。

@Component(modules = {AndroidInjectionModule.class,
        BinderModule.class,
        SplashModule.class,    // <== 1.
        QuestionModule.class}) // <== 2.
public interface AppComponent { .. }

由于您希望每个 Activity 有一个实例,因此无需将模块添加到AppComponent. 您应该能够从中删除这两个模块。


推荐阅读