Dagger 2.10 Android子组件和构建器 [英] Dagger 2.10 Android subcomponents and builders

查看:77
本文介绍了Dagger 2.10 Android子组件和构建器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用新的(在2.10中)dagger.android类,我试图使用依赖于其他模块的Subcomponent注入事物,因此,有了一个带有针对这些模块的设置器的Builder. https://google.github.io/dagger/android.html 上的文档描述了这,但尚不清楚如何实际编写和/或调用这些设置器.

Using the new (in 2.10) dagger.android classes, I'm trying to inject things using a Subcomponent that depends on other Modules, and, therefore, has a Builder with setters for those modules. The documentation on https://google.github.io/dagger/android.html describes this, but is not clear on how to actually write and/or invoke those setters.

从以上链接引用:

AndroidInjection.inject()从应用程序获取DispatchingAndroidInjector并将您的活动传递给inject(Activity). DispatchingAndroidInjector为您的活动的类(即YourActivitySubcomponent.Builder)查找AndroidInjector.Factory,创建AndroidInjector(即YourActivitySubcomponent),然后将您的活动传递给inject(YourActivity).

AndroidInjection.inject() gets a DispatchingAndroidInjector from the Application and passes your activity to inject(Activity). The DispatchingAndroidInjector looks up the AndroidInjector.Factory for your activity’s class (which is YourActivitySubcomponent.Builder), creates the AndroidInjector (which is YourActivitySubcomponent), and passes your activity to inject(YourActivity).

在我看来,为了能够调用Builder的设置者,我需要进入某个地方并确保Builder具有所有必要的数据?我看到的问题是,在运行时,当AndroidInjector调用为我的子组件生成的生成器时,我得到一个IllegalStateException: MODULE must be set.

It seems to me that in order to be able to call the setters for the Builder, I need to get in there somewhere and ensure the Builder has all the necessary data? The problem I'm seeing is that at runtime, I get an IllegalStateException: MODULE must be set, when the generated builder for my Subcomponent is invoked by AndroidInjector.

有问题的子组件实际上是一个片段,而不是一个活动,但是我不确定这应该很重要.有关如何执行此操作的任何想法?

The Subcomponent in question is in fact for a Fragment, not an Activity, but I'm not sure that should matter. Any ideas about how to do this?

推荐答案

简而言之,您应该

In short, you're supposed to override the call to seedInstance on the Builder (which is an abstract class instead of an interface) to provide other modules you need.

edit :在执行此操作之前,请检查并确保您确实需要通过该模块.正如 Damon在单独的答案中添加一样,如果您要为Android类制作特定的模块,则可以依靠此时自动注入该类,以将配置或实例从图形中拉出.如果仅从您的Module中消除构造函数参数会更容易,那就支持他的方法,因为这样可以避免不必要的实例和虚拟方法调用,因此还可以提供更好的性能.

edit: Before you do, check and make sure that you really need to pass that Module. As Damon added in a separate answer, if you're making a specific Module for your Android class, you can rely on the automatic injection of that class to pull the configuration or instance out of the graph at that point. Favor his approach if it's easier just to eliminate the constructor parameters from your Module, which also may provide better performance as they avoid unnecessary instances and virtual method calls.

首先,在30秒内 dagger.android :不是让每个Activity或Fragment都知道其父级,而是Activity(或Fragment)调用AndroidInjection.inject(this),这会检查应用程序中的HasActivityInjector (或HasFragmentInjector的父片段,活动和应用程序).想法是,您将绑定贡献给创建的multibindings创建的Map<Class, AndroidInjector.Factory>,其中您贡献的绑定几乎总是 子组件构建器,而这些子组件生成器构建特定于对象的子组件.

First, dagger.android in 30 seconds: Rather than having each Activity or Fragment know about its parent, the Activity (or Fragment) calls AndroidInjection.inject(this), which checks the Application for HasActivityInjector (or parent fragments, activity, and application for HasFragmentInjector). The idea is that you contribute a binding to a multibindings-created Map<Class, AndroidInjector.Factory>, where the contributed bindings are almost always subcomponent builders you write that build object-specific subcomponents.

您可能会从AndroidInjection.inject(this)AndroidInjector.Factory.create(T instance)得知,您没有太多机会将特定于活动或特定于片段的详细信息传递给Builder.取而代之的是,您的子组件构建器将覆盖seedInstance实现.就像seedInstance的文档中一样:

As you might tell from AndroidInjection.inject(this) and AndroidInjector.Factory.create(T instance), you don't get a lot of opportunity to pass Activity-specific or Fragment-specific details to your Builder. Instead, the idea is that your subcomponent builder overrides the seedInstance implementation. As in the docs for seedInstance:

提供要在已构建的AndroidInjector的绑定图中使用的instance.默认情况下,此方法用作BindsInstance方法,但是可以覆盖该方法,以提供需要引用该活动的任何模块.

Provides instance to be used in the binding graph of the built AndroidInjector. By default, this is used as a BindsInstance method, but it may be overridden to provide any modules which need a reference to the activity.

这应该是将传递给inject(Object)的实例.

This should be the same instance that will be passed to inject(Object).

看起来像这样:

@Subcomponent(modules = {OneModule.class, TwoModule.class})
public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {

  // inject(YourActivity) is inherited from AndroidInjector<YourActivity>

  @Builder
  public abstract class Builder extends AndroidInjector.Builder<YourActivity> {
    // Here are your required module builders:
    abstract Builder oneModule(OneModule module);
    abstract Builder twoModule(TwoModule module);

    // By overriding seedInstance, you don't let Dagger provide its
    // normal @BindsInstance implementation, but you can supply the
    // instance to modules or call your own BindsInstance:
    @Override public void seedInstance(YourActivity activity) {
      oneModule(new OneModule(activity));
      twoModule(new TwoModule(activity.getTwoModuleParameter()));
    }
  }
}

这里的假设是您需要等待模块的activity实例.如果没有,那么您还可以在绑定子组件时选择调用它们:

The assumption here is that you need to wait for the activity instance for the modules. If not, then you also have the option of calling those when you bind the subcomponent:

@Provides @IntoMap @ActivityKey(YourActivity.class)
AndroidInjector.Factory bindInjector(YourActivitySubcomponent.Builder builder) {
  return builder
      .oneModule(new OneModule(...))
      .twoModule(new TwoModule(...));
}

...但是如果您能做到这一点,那么您可以通过重写那些模块,实现一个可以提供Module的构造函数参数的零参数构造函数,并让Dagger像这样来更轻松地处理这些绑定.对于具有公共零参数构造函数的任何模块都适用.

...but if you can do that, then you could more-easily take care of those bindings by overriding those modules, implementing a zero-arg constructor that can supply the Module's constructor parameters, and letting Dagger create those as it does for any Modules with public zero-arg constructors.

这篇关于Dagger 2.10 Android子组件和构建器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆