我有这个 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()
静态方法?一个人不能打电话给另一个人吗?
(顺便说一句,我确实意识到我不再需要在我的应用程序资源中捆绑字体。这不是这里的问题。)
首先:Dagger 提前生成此代码,以便在模块化构建中获得更好的构建性能。正因为如此,我们不知道which(或两者,或两者都不需要),因此我们生成两者以防万一,并假设 Proguard 将能够删除任何未使用的内容。
那么两者实际上在做什么呢?
第一个(get()
方法)在该工厂表示的绑定被请求为Provider<T>
。这可以直接发生,也可以在绑定范围内发生,或者在其他一些情况下发生。
第二种情况就是我们所说的inlining。假设你有一个@Provides
模块中的方法,并且您的上有一个方法@Component
返回该类型。最理想的生成代码类似于:
@Override
public YourBinding y() {
return YourModule.yourProvidesMethod();
}
问题是,提供的方法可能无法从与组件相同的包中访问,因此我们生成这个“代理”方法,为 Dagger 提供正确的可访问性。它还可以访问该方法的所有参数,将它们擦除Object
如果需要的话。如果它们确实被删除了(将其视为泛型类型删除),我们需要将强制转换插入到正确的类型inside代理方法。
The Provider.get()
实现不需要这样,因为在那里,所有类型都应该可以由调用它的代码访问。
总而言之,我们想要生成两个版本,希望您应该只使用一个版本,而 Proguard 应该清理另一个版本。
希望有帮助!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)