作者:醒葛 | 来源:互联网 | 2022-12-31 14:50
我有这个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 {
private final Provider assetsProvider;
public TypefaceModule_ProvideRobotoLightFactory(Provider 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 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()
静态调用模块的方法?不能一个人打电话给对方?
(顺便说一下,我确实意识到我不再需要在我的应用资产中捆绑字体.这不是问题.)
1> 小智..:
首先,Dagger会提前生成此代码,因此在模块化构建中,您可以获得更好的构建性能。因此,我们不知道您将需要哪个(或两者,或都不需要),因此我们生成这两个参数只是为了以防万一,并假设Proguard将能够剥离所有未使用的东西。
那么,两者实际上都在做什么呢?
get()
当将此工厂表示的绑定请求为时,将调用第一个(方法)Provider
。这可以直接发生,也可以在绑定范围内发生,也可以在其他一些情况下发生。
第二种情况称为内联。假设您@Provides
在模块中有一个方法,并且在您的方法上有一个@Component
返回该类型的方法。生成的最理想的代码是这样的:
@Override
public YourBinding y() {
return YourModule.yourProvidesMethod();
}
事实是,provider方法可能无法从与您组件相同的包中访问,因此我们生成了此“ proxy”方法,该方法为Dagger提供了正确的可访问性。它还使该方法的所有参数都可以访问,并Object
在必要时将其删除。如果他们得到清除(认为这就像泛型类型擦除),我们需要再插入铸件正确类型内的代理方法。
该Provider.get()
实现不需要它,因为在那里,调用它的代码应该可以访问所有类型。
综上所述-我们想生成两个版本,希望您只使用其中一个,而Proguard应该清除另一个版本。
希望有帮助!