Dagger 2生成代码中proxyProvide的目的 [英] Purpose of proxyProvide in Dagger 2 generated code

查看:114
本文介绍了Dagger 2生成代码中proxyProvide的目的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个Dagger模块.我想了解生成的代码,因此可以验证我的Dagger配置是否最佳.

I have this Dagger module. I want to understand the generated code so I can verify that my Dagger configuration is optimal.

@Module
public class TypefaceModule {

    @Provides @Singleton @Named("Roboto Light")
    static Typeface provideRobotoLight(AssetManager assets) {
        return Typeface.createFromAsset(assets, "fonts/Roboto-Light.ttf");
    }

}

以下是生成的代码(匕首2.14.1):

Here's the generated code (Dagger 2.14.1):

public final class TypefaceModule_ProvideRobotoLightFactory implements Factory<Typeface> {
  private final Provider<AssetManager> assetsProvider;

  public TypefaceModule_ProvideRobotoLightFactory(Provider<AssetManager> assetsProvider) {
    this.assetsProvider = assetsProvider;
  }

  @Override
  public Typeface get() {
    return Preconditions.checkNotNull(
        TypefaceModule.provideRobotoLight(assetsProvider.get()),
        "Cannot return null from a non-@Nullable @Provides method");
  }

  public static TypefaceModule_ProvideRobotoLightFactory create(
      Provider<AssetManager> assetsProvider) {
    return new TypefaceModule_ProvideRobotoLightFactory(assetsProvider);
  }

  public static Typeface proxyProvideRobotoLight(AssetManager assets) {
    return Preconditions.checkNotNull(
        TypefaceModule.provideRobotoLight(assets),
        "Cannot return null from a non-@Nullable @Provides method");
  }
}

有两个功能几乎可以完成相同的功能:实例方法get()和静态方法proxyProvideRobotoLight().

There are two functions which do almost the same thing: the instance method get(), and the static method proxyProvideRobotoLight().

为什么Dagger会生成此代码的两个版本,而这两个版本都静态地调用模块的provide()方法?一个人不能打电话给另一个人吗?

Why has Dagger generated two versions of this code, which both call the module's provide() method statically? Can't one call the other?

(顺便说一句,我确实意识到我不再需要在应用程序资源中捆绑字体.这不是这里的问题.)

(Incidentally, I do realise that I no longer need to bundle fonts in my app assets. That's not the question here.)

推荐答案

首先:Dagger会提前生成此代码,因此在模块化构建中,您可以获得更好的构建性能.因此,我们不知道您将需要哪个(或两者都不是,或都不需要),因此我们生成这两个参数只是为了以防万一,并假设Proguard将能够剥离所有未使用的东西.

First off: Dagger generates this code ahead-of-time so that in a modularized build, you get better build performance. Because of that, we don't know which (or both, or neither) that you will need, so we generate both just in case, and assume that Proguard will be able to strip whatever is unused.

那么,两者实际上都在做什么?

当将此工厂表示的绑定请求为Provider<T>时,将调用第一个(get()方法).这可以直接发生,也可以在绑定作用域内发生,也可以在其他一些情况下发生.

The first (the get() method) is invoked when the binding that this factory represents is requested as a Provider<T>. That can happen either directly, or if the binding is scoped, or a few other scenarios.

第二种情况就是我们所说的 inline .假设模块中有一个@Provides方法,并且@Component上有一个返回该类型的方法.生成的最理想的代码是这样的:

The second case is what we call inlining. Suppose you have a @Provides method in a module, and you have a method on your @Component that returns that type. The most ideal code to generate is something like:

@Override
public YourBinding y() {
  return YourModule.yourProvidesMethod();
}

问题是,provider方法可能无法从与您组件相同的程序包中访问,因此我们生成了此"proxy"方法,该方法使Dagger具有正确的可访问性.它还使该方法的所有参数都可访问,并在必要时将其擦除为Object.并且如果确实将其擦除(例如,类似于通用类型擦除),则需要将强制类型转换插入到内部代理方法中的正确类型.

The thing is, that provides method may not be accessible from the same package as your component, so we generate this "proxy" method which gives Dagger the right accessibility. It also makes accessible all of the parameters to that method, erasing them to Object if necessary. And if they do get erased (think of this like generic type erasure), we need to then insert the casts to the correct types inside the proxy method.

Provider.get()实现不需要它,因为在那里,调用它的代码应该可以访问所有类型.

The Provider.get() implementation doesn't need that, because there, all of the types should are accessible by the code that invokes it.

因此,总而言之-我们想生成两个版本,希望您只使用一个版本,而Proguard应该清除另一个版本.

So to sum up - we want to generate both versions, hopefully you should only use one, and Proguard should clean up the other.

希望有帮助!

这篇关于Dagger 2生成代码中proxyProvide的目的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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