我有这个Dagger模块。我想了解生成的代码,以便验证我的Dagger配置是否最佳。
@Module
public class TypefaceModule {
@Provides @Singleton @Named("Roboto Light")
static Typeface provideRobotoLight(AssetManager assets) {
return Typeface.createFromAsset(assets, "fonts/Roboto-Light.ttf");
}
}
这里是生成的代码(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()
。
为什么Dagger生成了这个代码的两个版本,它们都静态调用模块的provide()
方法?一个人不能打电话给对方吗?
(顺便说一句,我确实意识到我不再需要在我的应用资产中捆绑字体。这不是问题所在。)
答案 0 :(得分:4)
首先:Dagger提前生成此代码,以便在模块化构建中获得更好的构建性能。因此,我们不知道哪个(或两者,或两者都不需要),所以我们生成两者以防万一,并假设Proguard能够剥离任何东西未使用的。
那么两者究竟在做什么?
当此工厂表示的绑定被请求为get()
时,将调用第一个(Provider<T>
方法)。这可以直接发生,或者如果绑定是作用域,或者其他一些场景。
第二种情况是我们称之为内联。假设您在模块中有@Provides
方法,并且您的@Component
上有一个返回该类型的方法。生成的最理想代码是:
@Override
public YourBinding y() {
return YourModule.yourProvidesMethod();
}
问题是,提供的方法可能无法从与组件相同的包中访问,因此我们生成了这个&#34;代理&#34;使Dagger具有正确的可访问性的方法。它还可以访问该方法的所有参数,必要时将它们删除到Object
。如果它们被删除(将其视为泛型类型擦除),我们需要将强制转换插入内部代理方法中的正确类型。
Provider.get()
实现并不需要它,因为在那里,所有类型都应该由调用它的代码访问。
总而言之 - 我们希望生成两个版本,希望您只使用一个版本,而Proguard应该清理另一个版本。
希望有所帮助!