我遇到类似this问题中的类似问题。 虽然接受的答案确实有帮助,但我缺少最后一块来解决问题。
我有2个Android库模块:common
和exp
,它取决于common
。
common
下的所有内容:
@Module
public class CommonModule {
@Singleton
@Provides
public Repository providesRepository() {
return new Repository();
}
}
@Singleton
@Component(modules={CommonModule.class})
public interface CommonComponent {
void inject(CommonClass commonClass);
/**
CommonClass needs instance of Repository
**/
}
public class CommonDIHolder {
public static CommonComponent sComponent;
public static void init() {
sComponent = DaggerCommonComponent.builder().build();
}
}
exp
下的所有内容:
@Module(includes={CommonModule.class})
public class ExpModule {
@Singleton
@Provides
public ExpResource provideExpResource() {
return new ExpResource();
}
}
@Singleton
@Component(modules={ExpModule.class}, dependencies={CommonComponent.class})
public interface ExpComponent {
void inject(ExpClass expClass);
/**
ExpClass needs instance of Repository and ExpResource
**/
}
public class ExpDIHolder {
public static ExpComponent sComponent;
public static void init() {
sComponent = DaggerExpComponent.builder()
.commonComponent(CommonDIHolder.sComponent)
.build();
}
}
我需要CommonClass
和ExpClass
同时收到Repository
的同一个实例。
此方法存在的问题是@Singleton
无法取决于@Singleton
。所以我必须将ExpComponent
的范围更改为名为@ExpScope
的自定义范围。然后我也将provideExpResource
更改为@ExpScope
。
然后我遇到一个错误,指出ExpComponent
可能不会引用具有不同范围的绑定。它指的是provideRepository
,它具有不同的范围(@Singleton
)。如果我将范围更改为ExpScope
,那么CommonComponent
将与provideRepository
具有不同的范围。
如果我将所有@Singleton
更改为@ExpScope
,则会收到以下错误消息:depends on scoped components in a non-hierarchical scope ordering
我该怎么办?或者我在这里做错了吗?
答案 0 :(得分:1)
仅使用一个@Singleton
范围内的组件
您应该只有一个@Singleton
范围的组件,如下所示:
@Singleton
@Component(modules={CommonModule.class, ExpModule.class})
public interface CommonComponent {
}
仅将“活动”,“片段”和“服务”指定为“组件”的显式注入目标
在Android应用中,您应该只将活动,片段和服务列为注入网站。您应该配置Dagger 2以注入其余的依赖项,而不必在其中调用component.inject(this)
。
例如,如果您的CommonClass
看起来像这样:
public class CommonClass {
@Inject Repository repository;
public class CommonClass() {
CommonComponentHolder.get().inject(this);
}
}
像这样重写:
public class CommonClass {
private final Repository repository;
@Inject
public class CommonClass(Repository repository) {
this.repository = repository;
}
}
现在,如果您有一个需要CommonClass
的活动或片段,并且您正在注入CommonComponent
或其子组件或相关组件之一,那么他们可以获取CommonClass
有线的实例具有正确的依赖关系:
public class MyActivity extends AppCompatActivity {
@Inject CommonClass commonClass;
public void onCreate(Bundle savedInstanceState) {
CommonComponentHolder.getComponent().inject(this);
}
}
使用子组件或相关组件指定注入目标
现在你有一个@Singleton
范围的组件,你可能想要为你的Activity或Fragment创建一个更窄范围的组件。您必须将其连接到CommonComponent
,因此请使用相关组件或子组件(从Dagger 2.10开始,首选子组件)。既然你说你已经尝试定义@ExpScope
,我认为缺少的部分是使用注入你的Activity或Fragment的@ExpScope
制作子组件或依赖组件。
顶层单例组件的内容如下:
@Singleton
@Component(modules={CommonModule.class, ExpModule.class})
public interface CommonComponent {
ExpComponent.Builder exComponent();
}
然后是子组件:
@ExpScope
@Subcomponent(modules = {NarrowerScopedModule.class})
public interface ExpComponent {
@Subcomponent.Builder
public interface Builder {
Builder narrowerScopedModule(NarrowerScopedModule narrowerScopedModule);
ExpComponent build();
}
}
中有很好的Android项目工作示例