作者:Mars丶fasfa | 来源:互联网 | 2023-02-08 11:40
以下所有内容均与匕首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;
// ...
}
每个活动都将其模块和子组件定义为(exactement相同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 {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder {}
}
最后,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);
}
问题:我该怎么做?
1> Jeff Bowman ..:
您需要在每个子组件上单独绑定:
@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 {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder {}
}
因为@BindsInstance Builder seedInstance(DemoActivity)
在Dagger 从DispatchingAndroidInjector调用的AndroidInjector.Builder中,Dagger 至少知道如何提供DemoActivity实例.但是,DemoActivity和Activity(或Context)之间没有内置绑定,因此必须在子组件而不是组件上进行绑定.通过将具有该绑定的模块放在适当的上,您可以确保在每个相应的子组件中绑定转到Dagger知道的正确类型.AndroidInjector.Builder.create()
@Subcomponent
Activity
请注意,@Binds @IntoMap @ActivityKey(...)
DemoActivityModule 中的绑定仍然需要转到ApplicationComponent,因此ApplicationComponent可以确定从要注入的Activity的类创建哪个子组件.您特别希望新的DemoActivitySubcomponentModule转到DemoActivitySubcomponent,以便在DemoActivity2Subcomponent无法看到它的地方创建Activity-to-DemoActivity.
作为旁注,您看到的问题是两个绑定之间的冲突Activity
,这发生在同一个组件中.说同一个范围是不对的,因为(尽管您可能会选择将@ActivityScope等范围注释添加到每个子组件中),但没有范围注释可以帮助您.这seedInstance
将仅适用于每个当前未扩展的子组件,它将与祖先组件中的绑定以及子组件特定的模块组合.