本文介绍了Dagger-在不同组件上获取相同实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我遇到类似的问题,例如这个问题。 虽然接受的答案确实有帮助,但我缺少解决问题的最后一部分。I'm having a similar problem like the one in this question.While the accepted answer does help, but I'm missing final piece to solve the problem.我有2个android库模块: common 和 exp 取决于 common 。I have 2 android library modules: common and exp which depends on common. 常见的所有内容:@Modulepublic 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 会收到存储库的相同实例。I need both CommonClass and ExpClass receive the same instance of Repository.此方法的问题在于 @Singleton 不能依赖 @Singleton 。因此,我必须将 ExpComponent 的范围更改为称为 @ExpScope 的自定义范围。然后,我也将 provideExpResource 也更改为 @ExpScope 。The problem with this approach is that @Singleton can't depends on @Singleton. So I have to change the scope of ExpComponent into self-defined scope called @ExpScope. Then I changed the provideExpResource into @ExpScope as well.然后我遇到一个错误,说 ExpComponent 可能未引用具有不同作用域的绑定。它指的是 provideRepository ,它具有不同的范围( @Singleton )。如果将范围更改为 ExpScope ,则 CommonComponent 的范围将与带有 provideRepository 的其他范围。Then I encountered an error saying that ExpComponent may not reference bindings with different scopes. It refers to the provideRepository which has different scope (@Singleton) on it. If I changed the scope into ExpScope then the CommonComponent will have different scope with provideRepository.如果我将所有 @Singleton 都更改为 @ExpScope 然后我会收到此错误消息:取决于非分层作用域排序中的作用域组件If I changed all @Singleton into @ExpScope then I receive this error message: depends on scoped components in a non-hierarchical scope ordering我该怎么办?还是我在这里使用错误的方法?What should I do? Or I'm doing the wrong approach here?推荐答案 仅使用一个 @ Singleton 作用域分量Use one and only one @Singleton scoped component您应该只有一个 @Singleton 这样的作用域组件:You should have one and only one @Singleton scoped component like this:@Singleton@Component(modules={CommonModule.class, ExpModule.class})public interface CommonComponent {} 仅将活动,片段和服务指定为组件的显式注入目标在Android应用中,您应仅将活动,片段和服务列为注入站点。您应该将Dagger 2配置为注入其余的依赖项,而不必在其中调用 component.inject(this)。In an Android app, you should only list Activities, Fragments and Services as injection sites. You should configure Dagger 2 to inject the rest of your dependencies without having to resort to calling component.inject(this) inside them.例如,如果您的 CommonClass 看起来像这样:For example, if your CommonClass looks like this: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 与正确的依赖项关联:Now when you have an Activity or Fragment that needs CommonClass and you are injecting with CommonComponent or one of its sub-components or dependent components, they can obtain instances of CommonClass wired with the correct dependencies:public class MyActivity extends AppCompatActivity { @Inject CommonClass commonClass; public void onCreate(Bundle savedInstanceState) { CommonComponentHolder.getComponent().inject(this); }} 使用子组件或从属组件来指定注入目标现在您有了一个 @Singleton 范围内的组件,您可能需要创建用于活动或片段的较窄范围的组件。您必须将其连接到 CommonComponent ,因此请使用依赖的组件或子组件(从Dagger 2.10开始,首选子组件)。因为您说过您已经尝试定义 @ExpScope ,所以我认为缺少的部分是使用 @ExpScope 会注入您的活动或片段。Now you have a @Singleton scoped component, you'll probably want to create a component for a narrower scope for your Activity or Fragment. You'll have to connect it to your CommonComponent, so use dependent components or subcomponents (subcomponents are preferred as of Dagger 2.10). Since you say you have already tried defining a @ExpScope, I think the missing piece is to make subcomponent or dependent component with the @ExpScope that injects your Activity or Fragment.顶级单例组件的操作类似于以下内容:Something like the following for the top-level singleton component:@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(); }}在 Google Android体系结构蓝图Github存储库 这篇关于Dagger-在不同组件上获取相同实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-30 07:32