您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > Android单排上王者系列之Dagger2注入原理解析
Android单排上王者系列之Dagger2注入原理解析Dagger2的注入原理原理的讲解我们通过小明来带我们学习。小明在看了MVP的实战解析和Dagger2的使用后知道了Dagger2该如何在MVP模式中使用,但是小明是一个要求上进的好同学,小明并不满足于如何使用,小明想钻研钻研源码,看看如何实现的。小明在钻研Dagger2的时候突然意识到Dagger2是采用注解的形式完成任务的,使用注解其实是不明智的选择,会大大消耗性能,影响应用的运行速度。小明看到这里有点疑惑了,既然注解这么影响性能,那为什么Dagger2还要使用注解呢?为什么Dagger2还这么被广泛的使用呢?于是小明到github上查看Dagger2的介绍官方介绍是AfastdependencyinjectorforAndroidandJava.Dagger2是一个Android和Java中的快速注射器。小明又疑惑了注解反射怎么是快速的呢?小明没有灰心又继续查看代码,终于发现Dagger2是和其他依赖注入框架是有区别的,Dagger2是通过apt插件在编译阶段生成注入代码的,也就是说反射只是在编译阶段使用了,而在应用运行的时候其实运行的是真正的Java代码并没有涉及到注解反射,小明终于明白了,难怪Dagger2是快速注入框架。小明有了这个重大发现后决定一鼓作气把Dagger2生成的代码给理清楚。编译阶段生成代码小明通过在Androidstudio中通过执行Build-RebuildProject,在app/build/generated/source/apt目录下发现生成了LoginPresenterComp_Factory类代码如下publicfinalclassLoginPresenterCompl_FactoryimplementsFactoryLoginPresenterCompl{privatefinalProviderILoginViewviewProvider;publicLoginPresenterCompl_Factory(ProviderILoginViewviewProvider){assertviewProvider!=null;this.viewProvider=viewProvider;}@OverridepublicLoginPresenterComplget(){returnnewLoginPresenterCompl(viewProvider.get());}publicstaticFactoryLoginPresenterComplcreate(ProviderILoginViewviewProvider){returnnewLoginPresenterCompl_Factory(viewProvider);}}为了对比小明又把LoginPresenterCompl的代码也找了出来代码如下publicclassLoginPresenterComplimplementsILoginPresenter{@InjectpublicLoginPresenterCompl(ILoginViewview){loginView=view;user=newUser(张三,123456);}......}仔细看看LoginPresenterCompl_Factory这个类,发现其中有三个方法构造方法构造方法中的参数viewProvider一个Provider类型的,而Provider的泛型参数是ILoginView,这个参数就是我们实例化LoginPresenterCompl需要的参数,在上篇中我们知道了该参数是一个依赖,是由MainModule提供的。get()方法在该方法中初始化了我们正在需要的LoginPresenterCompl对象create()方法在该方法中实例化了LoginPresenterCompl_Factory本类对象小明想既然上面的viewProvider是由MainModule提供的,那么就来看看MainModule对应的注入类吧MainModule_ProvideILogViewFactory代码如下publicfinalclassMainModule_ProvideILogViewFactoryimplementsFactoryILoginView{privatefinalMainModulemodule;publicMainModule_ProvideILogViewFactory(MainModulemodule){assertmodule!=null;this.module=module;}@OverridepublicILoginViewget(){returnPreconditions.checkNotNull(module.provideILogView(),Cannotreturnnullfromanon-@Nullable@Providesmethod);}publicstaticFactoryILoginViewcreate(MainModulemodule){returnnewMainModule_ProvideILogViewFactory(module);}}对应的MainModule代码如下@ModulepublicclassMainModule{privatefinalILoginViewview;publicMainModule(ILoginViewview){this.view=view;}@ProvidesILoginViewprovideILogView(){returnview;}}从结构中不难看出被@Provider注解修饰的方法会对应的生成Factory类,这个类中最主要的方法是get()方法,在该方法中调用了MainModule的provideILogView方法,而该方法是为了我们提供LoginPresenterCompl实例化参数的,LoginPresenterCompl的实例化是在LoginPresenterCompl_Factory的get()方法中完成的。实例化代码如下@OverridepublicLoginPresenterComplget(){returnnewLoginPresenterCompl(viewProvider.get());}1234在代码中可以看出实例化过程中参数是由viewProvider.get()提供的。咦!!!!在MainModule_ProvideILogViewFactory中的get()方法其实返回了我们实例化的参数。那么这个viewProvider是不是我们的MainModule_ProvideILogViewFactory呢?viewProvider是一个Provider类型,而MainModule_ProvideILogViewFactory实现了Factory接口,那Provider和Factory有没有联系呢?看这段代码publicinterfaceFactoryTextendsProviderT{}12发现Factory接口继承了Provider接口,所以其实viewProvider就是MainModule_ProvideILogViewFactory类型。看到这里小明终于明白了LoginPresenterCompl_Factory类和MainModule_ProvideILoginViewFactory类的关系了,也明白了实例化过程了。但是这些类的初始化和相关方法是如何被调用的,在哪里被调用的呢?还有两个重要的类小明没有看到。MainComponent和对应的DaggerMainComponent。代码如下MainComponent代码@Component(modules=MainModule.class)publicinterfaceMainComponent{publicvoidinject(LoginActivityactivity);}1234DaggerMainComponent代码publicfinalclassDaggerMainComponentimplementsMainComponent{privateProviderILoginViewprovideILogViewProvider;privateProviderLoginPresenterComplloginPresenterComplProvider;privateMembersInjectorLoginActivityloginActivityMembersInjector;privateDaggerMainComponent(Builderbuilder){assertbuilder!=null;initialize(builder);}publicstaticBuilderbuilder(){returnnewBuilder();}@SuppressWarnings(unchecked)privatevoidinitialize(finalBuilderbuilder){this.provideILogViewProvider=MainModule_ProvideILogViewFactory.create(builder.mainModule);this.loginPresenterComplProvider=LoginPresenterCompl_Factory.create(provideILogViewProvider);this.loginActivityMembersInjector=LoginActivity_MembersInjector.create(loginPresenterComplProvider);}@Overridepublicvoidinject(LoginActivityactivity){loginActivityMembersInjector.injectMembers(activity);}publicstaticfinalclassBuilder{privateMainModulemainModule;privateBuilder(){}publicMainComponentbuild(){if(mainModule==null){thrownewIllegalStateException(MainModule.class.getCanonicalName()+mustbeset);}returnnewDaggerMainComponent(this);}publicBuildermainModule(MainModulemainModule){this.mainModule=Preconditions.checkNotNull(mainModule);returnthis;}}}通过上面代码可以看出DaggerMainComponent实现了MainComponent接口并实现了其中的inject()方法。同时也提供了其他的辅助方法。小明决定从方法调用顺序开始入手查看DaggerMainComponent.builder().mainModule(newMainModule(this)).build().inject(this);1注入过程还记得在LoginActivity中添加的这个方法吗,分析DaggerMainComponent就从这段代码入手。1、DaggerMainComponent调用了builder方法小明找到builder()方法看看这个方法到底做了什么事publicstaticBuilderbuilder(){returnnewBuilder();}发现这个方法创建并返回了Builder对象Builder是什么东东呢?仔细看代码Build是DaggerMainCompone的内部类。2、DaggerMainCo
本文标题:Android单排上王者系列之Dagger2注入原理解析
链接地址:https://www.777doc.com/doc-2897227 .html