首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在子组件中使用AndroidInjector

如何在子组件中使用AndroidInjector
EN

Stack Overflow用户
提问于 2017-09-12 19:49:21
回答 1查看 1K关注 0票数 2

我想有以下几个

ApplicationComponent

  • subcomponentBlue( modules= ModuleX.class)
  • subcomponentRed ( modules= ModuleY.class)

假设我有四个活动A,B,C和D

如何使AndroidInjector工作这样我就可以

  • A,B有自己的子组件,它们是subcomponentBlue和
  • C,D有它们自己的子组件,它们是subcomponentRed的子组件
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-14 02:32:31

虽然没有一种内置的方法来做到这一点,但是您可以通过在应用程序中提供HasActivityInjector的实现来做到这一点。您需要重新创建dagger.android为您提供的一些细节,但这并没有那么糟糕。

请参考DaggerApplication的默认实现DispatchingAndroidInjector,它在其maybeInject方法中只需参考多绑定构建的Map<Class, AndroidInjector.Factory>来生成AndroidInjector并调用inject。如果您遵循dagger.android用户指南,那么每个AndroidInjector碰巧都是子组件,每个AndroidInjector.Factory恰好是使用@ContributesAndroidInjector安装的子组件生成器,但这些不是需求。

相反,您的应用程序将包含如下代码:

代码语言:javascript
复制
public class YourApplication extends Application implements HasActivityInjector {
  // Let's assume your application component calls inject(this) so these
  // @Inject fields are populated, and that you've instantiated some subcomponents
  // that are long-lived. Of course, you can inject your Subcomponent.Builder
  // interfaces instead, if you want a new subcomponent per activity.
  @Inject SubcomponentBlue subcomponentBlue;
  @Inject SubcomponentRed subcomponentRed;

  @Override public AndroidInjector<Activity> activityInjector() {
    // If you can use Java 8 syntax from Android, a lambda would work
    // nicely here, as in "return activity -> { ... };".
    return new AndroidInjector<Activity>() {
      @Override public void inject(Activity activity) {
        if (activity instanceof ActivityA) {
          // HERE'S THE MAGIC: We know that activity is an ActivityA,
          // and that subcomponentBlue has an ActivityA injector, so we
          // perform a cast and then use the Builder to create an
          // injector that we inject with.
          ActivityA aActivity = (ActivityA) activity;
          subcomponentBlue.aInjectorBuilder().create(aActivity).inject(aActivity);
        } elseif (activity instanceof ActivityB) { // ...
        } elseif (activity instanceof ActivityC) {
          ActivityC cActivity = (ActivityC) activity;
          subcomponentRed.cInjectorBuilder().create(cActivity).inject(cActivity);
        } elseif (activity instanceof ActivityD) { // ...
        } else {
          Exception aTantrum = new IllegalArgumentException("Injector not found");
          throw aTantrum;
        }
      }
    };
  }
}

上面的内容是有效的,但相当冗长。作为另一种选择,您可以手动将活动绑定到多绑定映射中,而不是使用@ContributesAndroidInjector,而是通过子组件访问它们:

代码语言:javascript
复制
@Module public class YourApplicationModule {
  @Provides @IntoMap @ActivityKey(ActivityA.class)
  static AndroidInjector.Factory<Activity> provideAInjector(
      SubcomponentBlue subcomponentBlue) {
    // Of course, you can also inject a SubcomponentBlue.Builder and
    // create a new one each time.
    return subcomponentBlue.aInjectorBuilder();
  }

  // Same for B, C, and D.
}

必要注意:在所有这些情况下,您都试图访问A、B、C和D的注射器,而不是它们的父子组件"red“和"blue”。这意味着您需要将注入器(子组件构建器)作为"red“和"blue”的公共API的一部分进行访问,并确定这些子组件的生命周期将是什么样子。他们长寿吗?每次活动?不管怎样,这并不是其他开发人员所期望的生命周期,所以请准备提供足够的文档。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46184303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档