以下所有内容均与dagger 2.10和dagger.android
包一起使用。
假设我有一门课,我想参加多项活动。
public class DemoSharedClass {
Activity activity;
@Inject public DemoSharedClass(Activity activity) {
this.activity = activity;
}
}
然后,使用最新的Dagger API,我的类被定义为
public class DemoActivity extends DaggerActivity {
@Inject DemoSharedClass demoSharedClass;
// ...
}
public class Demo2Activity extends DaggerActivity {
@Inject DemoSharedClass demoSharedClass;
// ...
}
每个活动都将其模块和子组件定义为(Demo2Activity
的相同内容)
@Module(subcomponents = DemoActivitySubcomponent.class)
public abstract class DemoActivityModule {
@Binds
@IntoMap
@ActivityKey(DemoActivity.class)
abstract AndroidInjector.Factory<? extends Activity>
bindDemoActivityInjectorFactory(DemoActivitySubcomponent.Builder builder);
// This is set so SharedClass can be injected using its constructor
// There is the same in Demo2ActivityModule
@Binds abstract Activity bindActivity(DemoActivity demoActivity);
}
@Subcomponent
public interface DemoActivitySubcomponent extends AndroidInjector<DemoActivity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<DemoActivity> {}
}
最后,app组件定义为
@Component(modules = {
ApplicationModule.class,
AndroidInjectionModule.class,
DemoActivityModule.class,
Demo2ActivityModule.class,
})
interface DemoApplicationComponent {
DemoApplication injectApplication(DemoApplication application);
}
现在,我在构建项目时遇到了这个错误:
Error:(11, 11) error: [dagger.android.AndroidInjector.inject(T)] android.app.Activity is bound multiple times:
@Binds android.app.Activity dagger.demo.DemoActivityModule.bindActivity(dagger.demo.DemoActivity)
@Binds android.app.Activity dagger.demo.Demo2ActivityModule.bindActivity(dagger.demo.Demo2Activity)
我收到错误,我认为这是因为它们属于相同的范围,即应用程序组件。
我考虑过为两个DemoSubcomponents创建一个公共模块,它看起来像下面这样,但有类似的错误。
@Module
public abstract class SharedClassModule {
@Binds abstract Activity bindContext(DemoActivity demoActivity);
@Binds abstract Activity bindContext(Demo2Activity demo2Activity);
}
问题:我该怎么做?
答案 0 :(得分:5)
您需要在每个子组件上单独绑定:
@Module interface DemoActivitySubcomponentModule {
@Binds abstract Activity bindContext(DemoActivity demoActivity);
// ...other bindings unique to DemoActivity and not DemoActivity2
}
@Subcomponent(modules={DemoActivitySubcomponentModule.class})
public interface DemoActivitySubcomponent extends
AndroidInjector<DemoActivity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<DemoActivity> {}
}
由于AndroidInjector.Builder中的@BindsInstance Builder seedInstance(DemoActivity)
,Dagger从AndroidInjector.Builder.create()
调用DispatchingAndroidInjector,Dagger确实知道如何至少提供DemoActivity实例。但是,DemoActivity和Activity(或Context)之间没有内置绑定,因此必须在子组件而不是组件上进行绑定。通过将具有该绑定的模块放在适当的@Subcomponent
上,可以确保在每个相应的子组件中Activity
绑定转到Dagger知道的正确类型。
请注意,DemoActivityModule中的@Binds @IntoMap @ActivityKey(...)
绑定仍需要转到ApplicationComponent,因此ApplicationComponent可以从正在注入的Activity类中确定要创建的子组件。您特别希望新的DemoActivitySubcomponentModule转到DemoActivitySubcomponent,以便在DemoActivity2Subcomponent无法看到它的地方生成Activity-to-DemoActivity。
作为旁注,您看到的问题是Activity
的两个绑定之间的冲突,它发生在同一个组件中。说同一个范围是不对的,因为(尽管您可能会选择将@ActivityScope等范围注释添加到每个子组件中),但没有范围注释可以帮助您。 seedInstance
仅适用于每个当前未扩展的子组件,它将与祖先组件中的绑定以及特定于子组件的模块结合使用。