当前位置: 首页 > news >正文

网站维护广州建网站wordpress 滑块验证码

网站维护广州建网站,wordpress 滑块验证码,在线编写html网页代码,互联网营销师证书查询入口Android 12 源码分析 —— 应用层 三#xff08;SystemUIFactory及其Dependency解析#xff09; 在上一篇文章中#xff0c;介绍了SystemUI的启动流程#xff0c;并且简单提及了Dagger2用来管理各个SystemUI中要用的依赖。而这部分代码就在#xff1a;mContextAvailableC…Android 12 源码分析 —— 应用层 三SystemUIFactory及其Dependency解析 在上一篇文章中介绍了SystemUI的启动流程并且简单提及了Dagger2用来管理各个SystemUI中要用的依赖。而这部分代码就在mContextAvailableCallback.onContextAvailable(this);流程中。而这部分流程我们只是一笔带过并没有仔细分析。 接下来将会从这个调用开始介绍SystemUI中Componentsubcomponent的初始化并理解应该怎么使用这些Component。 本文会先以一个例子简单引入Dagger2中对各个注解的生成模板然后在介绍SystemUI中重要component和subcomponent的创建过程最后过渡到一个关键的类Dependency 注意此处之所以另起一个例子来说明Dagger2的生成模板完全是因为Dagger2对SystemUI的生成代码太多导致不太好列成文档 理解Dagger2的模板 为了能够更好理解Dagger2的生成代码的模板我们按照如下的例子进行编写然后查看生成的类. 将下面的代码放入一个DemoComponent.java的文件中 //最顶层的Component其有两个模块分别为 // DemoSubComponent1.DemoModule1 // DemoSubComponent2.DemoModule2 //最顶层Component提供两个接口用于得到SubComponent的Factory和Builder类 Component(modules {DemoSubComponent1.DemoModule1.class,DemoSubComponent2.DemoModule2.class}) public interface DemoComponent {DemoSubComponent1.Factory getSubComponent1Factory();DemoSubComponent2.Builder getSubComponent2Builder(); }//SubComponent1提供如下两个功能 // 1. 获得DemoAClass对象 // 2. 向DemoInject对象中注入需要的对象 SysUISingleton Subcomponent interface DemoSubComponent1{Subcomponent.Factoryinterface Factory {DemoSubComponent1 create();}DemoAClass getAClass();void inject(DemoInject inject);//SubComponent1隶属于的模块//指定了DemoInterface 和DemoBinds之间的关系当需要DemoInterface的时候// Dagger2会创建对应的DemoBinds对象Module(subcomponents DemoSubComponent1.class)abstract class DemoModule1{Bindsabstract DemoInterface getInterface(DemoBinds bindings);} }//SubComponent2,提供一个功能 // 1. 获取DemoBClass对象 Subcomponent interface DemoSubComponent2{//为了和SubComponent1作区分这里使用了Builder类来创建SubComponent2Subcomponent.Builderinterface Builder {DemoSubComponent2 build();}DemoBClass getBClass();//SubComponent2隶属的模块该模块还提供了一个ProvidesModule(subcomponents DemoSubComponent2.class)class DemoModule2{//当需要DemoProvider对象的时候就会调用此方法ProvidesDemoProvider getProvider(){return new DemoProvider();}} }//用于演示Binds interface DemoInterface{void test(); }//用于演示Binds class DemoBinds implements DemoInterface{InjectDemoBinds(){}Overridepublic void test() {} }//用于演示Provides class DemoProvider{}//用于演示inject函数 class DemoInject{InjectDemoAClass a; }//用于演示生命周期 SysUISingleton class DemoAClass{Injectpublic DemoAClass(){} }//用于演示返回的对象 class DemoBClass{Injectpublic DemoBClass(){} }有了上面所画的图接下来查看Dagger2根据图生成的文件生成的文件有 DaggerDemoComponent.javaDemoAClass_Factory.javaDemoBClass_Factory.javaDemoBinds_Factory.javaDemoInject_MembersInjector.javaDemoSubComponent2_DemoModule2_GetProviderFactory.javaDemoSubComponent2_DemoModule2_Proxy.java 接下来我们挨个查看生成的7个文件分别是什么内容DaggerDemoComponent.java中会使用剩下的6个类。因此我们先看剩下的6个类最后再查看DaggerDemoFactory.java DemoAClass_Factory,DemoBClass_Factory,DemoBinds_Factory DemoAClass_Factory的源码如下 //对于任何类来讲只要其构造函数带有Inject则Dagger2都会创建一个对应的工厂类 //叫做XXX_Factory它实现了FactoryT接口 //欲使用这个工厂类则调用create()方法得到这个工厂类的实例,工厂类的实例永远只有一个 //欲使用这个工厂类产生的对象则调用newInstance()方法得到工厂类的产生对象 //工厂类产生的对象可以有多个 public final class DemoAClass_Factory implements FactoryDemoAClass {Overridepublic DemoAClass get() {return newInstance();}public static DemoAClass_Factory create() {return InstanceHolder.INSTANCE;}public static DemoAClass newInstance() {return new DemoAClass();}//用于缓存工厂类实例private static final class InstanceHolder {private static final DemoAClass_Factory INSTANCE new DemoAClass_Factory();} }DemoBClass_Factory,DemoBinds_Factory同DemoAClass_Factory一模一样不再啰嗦。 DemoInject_MembersInjector DemoInject_MembersInjector用于辅助成员的注入因为在DemoInject类中如下的代码 class DemoInject{InjectDemoAClass a; }整个辅助类源码如下 //每一个辅助注入的类都是MembersInjectorT的具体实现 //在实现中,对要注入的成员使用ProviderT表示抽象为T的提供者。它会在辅助类创建的时候被 //初始化好 // 对被注入的类使用instance表示 //同工厂类一样辅助注入类的实例化也是通过create()方法进行 //同工厂类不一样的是每次create都会创建不同的辅助注入对象 //注入方式则直接调用injectMembers()函数进行 public final class DemoInject_MembersInjector implements MembersInjectorDemoInject {private final ProviderDemoAClass aProvider;public DemoInject_MembersInjector(ProviderDemoAClass aProvider) {this.aProvider aProvider;}public static MembersInjectorDemoInject create(ProviderDemoAClass aProvider) {return new DemoInject_MembersInjector(aProvider);}Overridepublic void injectMembers(DemoInject instance) {injectA(instance, aProvider.get());}InjectedFieldSignature(com.android.systemui.dagger.DemoInject.a)public static void injectA(Object instance, Object a) {((DemoInject) instance).a (DemoAClass) a;} }上面的辅助注入类也很简单接着往下看 DemoSubComponent2_DemoModule2_GetProviderFactory DemoSubComponent2_DemoModule2_GetProviderFactory类表示的是对Provides的实现工厂类源码如下 //对于任何一个被Provides标记的函数Dagger2都会创建一个提供者工厂类它实现了FactoryT //同DemoAClass工厂类一样它也会有一个create()方法用于实例化提供者工厂类 //不同之处在于每次调用都会创建一个新的提供者工厂类//只有需要提供者工厂类生产提供者时才会调用get()方法用于返回生产出来的对象。public final class DemoSubComponent2_DemoModule2_GetProviderFactory implements FactoryDemoProvider {private final DemoSubComponent2.DemoModule2 module;public DemoSubComponent2_DemoModule2_GetProviderFactory(DemoSubComponent2.DemoModule2 module) {this.module module;}Overridepublic DemoProvider get() {return getProvider(module);}public static DemoSubComponent2_DemoModule2_GetProviderFactory create(DemoSubComponent2.DemoModule2 module) {return new DemoSubComponent2_DemoModule2_GetProviderFactory(module);}public static DemoProvider getProvider(DemoSubComponent2.DemoModule2 instance) {return Preconditions.checkNotNullFromProvides(instance.getProvider());} }上面的代码依然很简单不再啰嗦 DemoSubComponent2_DemoModule2_Proxy DemoSubComponent2_DemoModule2_Proxy是对抽象模块的表示源码如下 public final class DemoSubComponent2_DemoModule2_Proxy {private DemoSubComponent2_DemoModule2_Proxy() {}public static DemoSubComponent2.DemoModule2 newInstance() {return new DemoSubComponent2.DemoModule2();} }在DemoModule2中没有任何需要实现的地方且Binds已经语义足够明显所以上面生成的类没有任何过多的地方。较简单 接下来就是看看DaggerDemoComponent如何使用上面创建的类来处理他们之间的依赖关系 DaggerDemoComponent DaggerDemoComponent是整个依赖注入的入口其源码如下 //实现我们的DemoComponent接口其命名为DaggerAAA_BBB。其中下划线后面的名字为内部类的名字 public final class DaggerDemoComponent implements DemoComponent {private DaggerDemoComponent() {}//builder()方法和create()方法都是为了创建DaggerDemoComponent的实例public static Builder builder() {return new Builder();}public static DemoComponent create() {//委托给Builder类创建return new Builder().build();}//返回subcomponent1的Factory类用于创建subcomponent1Overridepublic DemoSubComponent1.Factory getSubComponent1Factory() {//见后文return new DemoSubComponent1Factory();}//返回subcomponent2的Bulder类用于创建subcomponent2Overridepublic DemoSubComponent2.Builder getSubComponent2Builder() {return new DemoSubComponent2Builder();}//用于创建DaggerDemoComponent,在这个类中只是简单的new了一个DaggerDemoComponent即可public static final class Builder {private Builder() {}Deprecatedpublic Builder demoModule2(DemoSubComponent2.DemoModule2 demoModule2) {Preconditions.checkNotNull(demoModule2);return this;}public DemoComponent build() {return new DaggerDemoComponent();}}//实现DemoSubComponent1的Factory接口该接口提供create()方法来创建对应的实例private final class DemoSubComponent1Factory implements DemoSubComponent1.Factory {Overridepublic DemoSubComponent1 create() {//创建DemoSubComponent1的实例对象并返回return new DemoSubComponent1Impl();}}//subcomponet1的具体实现private final class DemoSubComponent1Impl implements DemoSubComponent1 {private ProviderDemoAClass demoAClassProvider;private DemoSubComponent1Impl() {initialize();}//辅助构造函数对DemoAClass的提供者进行初始化//因为我们将DemoAClass的生命周期和DemoSubComponent1的生命周期都标记为//SysUISingleton//所以他们同生同死为了达到这个效果需要在subcomponent1中持有对DemoAClass的提供者//而不是每次重新创建(对比下面的getBClass()函数)//这样在需要DemoAClass的地方(如getAClass()函数)就直接让提供者来提供而提供者保证了//每次都提供同一个对象//DemoAClass的提供者我们首先想到的就是前面介绍过的DemoAClass_Factory工厂类//调用其newInstance()//就会创建一个DemoAClass对象。但是它并不能保证每次提供同一个对象因此再次对//DemoAClass_Factory进行封装//这个封装就是DoubleCheck对象,它保证了每次提供同一个对象同时也保证了线程安全//DoubleCheck最终也会使用DemoAClass_Factory类来实例化DemoAClass对象SuppressWarnings(unchecked)private void initialize() {this.demoAClassProvider DoubleCheck.provider(DemoAClass_Factory.create());}//调用DemoAClass的提供者让其提供同一个对象Overridepublic DemoAClass getAClass() {return demoAClassProvider.get();}//向DemoInject中注入需要的成员Overridepublic void inject(DemoInject inject) {injectDemoInject(inject);}//调用对应的辅助注入类注入需要的成员private DemoInject injectDemoInject(DemoInject instance) {DemoInject_MembersInjector.injectA(instance, demoAClassProvider.get());return instance;}}//subcomponnet2的Builder接口实现private final class DemoSubComponent2Builder implements DemoSubComponent2.Builder {Overridepublic DemoSubComponent2 build() {//创建subcomponent2对象并直接返回return new DemoSubComponent2Impl();}}//subcomponent2的具体实现类private final class DemoSubComponent2Impl implements DemoSubComponent2 {//因为DemoSubComponent2和DemoBClass并不是同一生命周期所以每次都创建一个新的//DemoBClass对象返回//因此也就不需要相应的提供者类也就不需要相应的对提供者类进行初始化 private DemoSubComponent2Impl() {}Overridepublic DemoBClass getBClass() {return new DemoBClass();}} }在Component中完成了如下的工作 实现了componentsubcomponent以及他们对应的Builder, Factory类subcomponent是component的内部类实现对应的接口方法这些方法会委托给其他的xxx_Factory,xxxx_MembersInjector辅助类来完成被委托的xxx_Factory工厂类,xxx_MembersInjector辅助类都会被正确的初始化 至此我们对Dagger2生成的模板有了一个整体把握并对其中的实现细节做了一些注释说明。 接下来我们继续看看SystemUI中的重要组件的创建过程 SystemUI 创建Dagger2依赖的起点 第一篇文章我们一笔带过了SystemUIApplication.onCreate()中的mContextAvailableCallback.onContextAvailable(this). 这就是Dagger2创建依赖的起点mContextAvailableCallback的赋值在SystemUIAppComponentFactory.java中。 如下 NonNull Override //此函数在创建SystemUIApplication之前调用 public Application instantiateApplicationCompat(NonNull ClassLoader cl, NonNull String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {//调用父类方法创建Application此处的app实例为SystemUIApplicationApplication app super.instantiateApplicationCompat(cl, className);if (app instanceof ContextInitializer) {//给SystemUIApplication的mContextAvailableCallback赋值((ContextInitializer) app).setContextAvailableCallback(context - {//SystemUIApplication的onCreate处开始调用//1. 首先创建SystemUIFactory(SystemUIFactory会负责创建各种依赖)//2. 然后马上注入SystemUIAppComponentFactory所需的成员(即// ContextComponentHelper)SystemUIFactory.createFromConfig(context);SystemUIFactory.getInstance().getSysUIComponent().inject(SystemUIAppComponentFactory.this);});}return app; }从上面我们看见了SystemUIFactory调用静态方法createFromConfig进行创建。从名字也能猜测一二从配置中创建SystemUIFactory 唉这个就值得思考了为何要从配置中创建难道可以配置成不同的SytemUIFactory吗每个SystemUIFactory有什么区别吗 我们带着问题往下看 SystemUIFactory SystemUIFactory从名字上似乎是SystemUI的工厂类。在上一篇文章Android 12 源码分析 —— 应用层 二SystemUI大体组织和启动过程http://t.csdn.cn/AuzsL的自定义组件小节中我们自定以的组件继承了SystemUI 难道SystemUIFactory是它的工厂类 我们来看看源码为了减少干扰我们从上一小节中的createFromConfig方法开始查看如下 public static void createFromConfig(Context context) {createFromConfig(context, false); }VisibleForTesting //最终调用的地方 public static void createFromConfig(Context context, boolean fromTest) {//1. 如果SystemUIFactory即mFactory已经存在则什么也不做if (mFactory ! null) {return;}//2. 倘若1不满足则读取配置文件中的类名然后使用反射创建这个对象//config_systemUIFactoryComponent的值即为com.android.systemui.SystemUIFactory//那么请思考是不是还有另外的类名事实上是有的还可以为//com.android.systemui.tv.TvSystemUIFactory.我们后面来比较他们之间的区别final String clsName context.getString(R.string.config_systemUIFactoryComponent);if (clsName null || clsName.length() 0) {throw new RuntimeException(No SystemUIFactory component configured);}//3. 创建完成对象之后则调用init方法try {Class? cls null;cls context.getClassLoader().loadClass(clsName);mFactory (SystemUIFactory) cls.newInstance();mFactory.init(context, fromTest);} catch (Throwable t) {Log.w(TAG, Error creating SystemUIFactory component: clsName, t);throw new RuntimeException(t);} }接下来继续进入其初始化函数中如下 VisibleForTestingpublic void init(Context context, boolean fromTest)throws ExecutionException, InterruptedException {//是否要运行初始化的一个判断全部满足下面的条件则初始化//1. 非测试模块运行//2. 是主用户//3. 是主进程mInitializeComponents !fromTest android.os.Process.myUserHandle().isSystem() ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName());//又见GlobalRootComponent。在上一篇文章中已经提及过//这里就是去构建整个应用最最顶层的那个ComponentmRootComponent buildGlobalRootComponent(context);//从GlobalRootComponent中获取需要创建依赖的Builder。然后创建依赖//1. 先创建WmComponent 这是一个与SysUIComponent站在同一维度的Component它负责提供WindowManager相关的东西此处可不用太过在意后面会详解mWMComponent mRootComponent.getWMComponentBuilder().build();if (mInitializeComponents) {//然后初始化mWMComponent.init();}//2. 再创建SysUIComponentSysUIComponent.Builder builder mRootComponent.getSysUIComponent();if (mInitializeComponents) {//将需要的各种食材放入Builder最后build()一下就是最终对象//使用Builder可以不用考虑这些函数的调用顺序他们会在Builder类中被处理好builder prepareSysUIComponentBuilder(builder, mWMComponent).setPip(mWMComponent.getPip()).setLegacySplitScreen(mWMComponent.getLegacySplitScreen()).setSplitScreen(mWMComponent.getSplitScreen()).setOneHanded(mWMComponent.getOneHanded()).setBubbles(mWMComponent.getBubbles()).setHideDisplayCutout(mWMComponent.getHideDisplayCutout()).setShellCommandHandler(mWMComponent.getShellCommandHandler()).setAppPairs(mWMComponent.getAppPairs()).setTaskViewFactory(mWMComponent.getTaskViewFactory()).setTransitions(mWMComponent.getTransitions()).setStartingSurface(mWMComponent.getStartingSurface()).setTaskSurfaceHelper(mWMComponent.getTaskSurfaceHelper());} else {builder prepareSysUIComponentBuilder(builder, mWMComponent).setPip(Optional.ofNullable(null)).setLegacySplitScreen(Optional.ofNullable(null)).setSplitScreen(Optional.ofNullable(null)).setOneHanded(Optional.ofNullable(null)).setBubbles(Optional.ofNullable(null)).setHideDisplayCutout(Optional.ofNullable(null)).setShellCommandHandler(Optional.ofNullable(null)).setAppPairs(Optional.ofNullable(null)).setTaskViewFactory(Optional.ofNullable(null)).setTransitions(Transitions.createEmptyForTesting()).setStartingSurface(Optional.ofNullable(null)).setTaskSurfaceHelper(Optional.ofNullable(null));}//创建然后初始化mSysUIComponent builder.build();if (mInitializeComponents) {mSysUIComponent.init();}//3. 通过SysUIComponent获得Dependency对象然后调用start()函数进行初始化,// (似乎叫做init()函数更加合理一点)Dependency dependency mSysUIComponent.createDependency();dependency.start();}在SystemUIFactory.init()函数中主要做了四件事 创建并初始化GlobalRootComponent创建并初始化WMComponent创建并初始化SysUIComponent创建并初始化Dependency 这4个对象即为SystemUI整个应用需要用到的组件通过这4个组件就可以得到Dagger2中的各种各样的依赖。 在挨个介绍这4个对象之前。我们先处理一下前面的疑问分别有 SystemUIFactory为何要从配置中创建SystemUIFactory的命名是不是感觉有些奇怪了 回答问题1因为SystemUIFactory不仅仅可以直接实例化SysetmUIFactory,有时还需要实例化SystemUIFactory的子类(比如TvSystemUIFactory)之所以需要有一个TvSystemUIFactory,是因为它需要一个不同版本的GlobalRootComponent叫做TvGloabRootComponent.而这个TvGlobalRootComponent继承于GlobalRootComponent 回答问题2显然SystemUIFactory提供的实例创建更应该叫GloablRootComponentFactory。而不应该叫SystemUIFactory.我想这也是开发人员不够严谨的地方。 当然也可能还有我未理解到的意思 此时SystemUIFactory其实已经没有什么内容可以介绍了剩下的内容无外乎getter内容简单此处略过 接下来就是几个Component的创建过程了 GlobalRootComponent GlobalRootComponent的创建需要从它的图说起。在Android 12 源码分析 —— 应用层 二SystemUI大体组织和启动过程http://t.csdn.cn/AuzsL一文中我们给GlobalRootComponent定义了一个Builder接口。 如下 Singleton Component(modules {GlobalModule.class,SysUISubcomponentModule.class,WMModule.class}) public interface GlobalRootComponent {Component.Builderinterface Builder {BindsInstanceBuilder context(Context context);GlobalRootComponent build();}//省略无关紧要部分 }那么Dagger2对这个Builder是怎么生成的呢 Dagger2生成的GlobalRootComponent.Builder 在编译的过程中上面的Builder接口将会被Dagger2实现并生成一个名叫Builder的类。如下 该类位于 out/soong/.intermediates/frameworks/base/packages/SystemUI/SystemUI-core/android_common/kapt/gen/sources/com/android/systemui/dagger/DaggerGlobalRootComponent.javaprivate static final class Builder implements GlobalRootComponent.Builder {private Context context;Overridepublic Builder context(Context context) {//1. 先判断传入的参数是否为空//2. 将传入的参数赋值给内成员这也是在上一篇文章中提及的BindsInstance的语义this.context Preconditions.checkNotNull(context);return this;}Overridepublic GlobalRootComponent build() {//1. 先判断context是否为空//2. new一个DaggerGlobalRootComponennt对象该对象就是Dagger2中实现// GlobalRootComponent接口的对象Preconditions.checkBuilderRequirement(context, Context.class);return new DaggerGlobalRootComponent(new GlobalModule(), context);}}接下来我们看看Dagger2对GlobalRootComponent的实现细节。 Dagger2生成的GlobalRootComponent 生成的文件位于 out/soong/.intermediates/frameworks/base/packages/SystemUI/SystemUI-core/android_common/kapt/gen/sources/com/android/systemui/dagger/DaggerGlobalRootComponent.java内容特别多为了简化分析我会缩进部分代码并对其中的实现细节进行简化因为他们的实现和前面介绍的模板几乎没有差别现在只需对其结构进行了解。 public final class DaggerGlobalRootComponent implements GlobalRootComponent {//定义一个成员变量类型为ProviderT 它可以通过//ProviderT.get() 得到对应的具体的对象//正是这个get()函数可以让成员真正被需要的时候才初始化//这样可以减少内存的使用//可将其理解为Context的提供者(同前面的模板一起理解几乎可以肯定它的实现为// DoubleCheck类)private ProviderContext contextProvider;//省略余下的类似的成员定义//构造器函数Dagger2根据我们画的图会正确的处理构造函数所需的依赖private DaggerGlobalRootComponent(GlobalModule globalModuleParam, Context contextParam) {this.context contextParam;initialize(globalModuleParam, contextParam);}//辅助构造函数的方法用于初始化成员变量SuppressWarnings(unchecked)private void initialize(final GlobalModule globalModuleParam, final Context contextParam) {//在方法体中Dagger2根据我们画的图自动去找寻需要的对象并初始化本对象成员//这也正是Dagger2的最大作用它可以简化我们的代码编写。自动帮我们完成各种各样的依赖//方法体中的赋值相对简单。不做过多介绍//这里面其实就是使用DoubleCheck对成员进行初始化(结合前面的模板进行思考)} //同构造函数一样mainResources你也不需要知道为什么会出现在这个地方(这属于Dagger2的内部// 细节)。Dagger2会自动处理好对于这个函数的调用private Resources mainResources() {//AAA_BBBFactory通常表示AAA类的BBB方法的工厂类它实现了FactoryT接口return FrameworkServicesModule_ProvideResourcesFactory.provideResources(context);}//同MainResources()函数一样Dagger2自动处理好其调用private Executor mainExecutor() {return GlobalConcurrencyModule_ProvideMainExecutorFactory.provideMainExecutor(context);}//这个是实现的GlobalRootComponent的接口.在这个接口中直接new了一个对象并返回//倘若每次调用这个方法则会创建不同的对象。这是因为他们的生命周期不一样//GlobalRootComponent的生命周期为SingleTton//而WMComponent.Builder的生命周期为WMSingletonOverridepublic WMComponent.Builder getWMComponentBuilder() {return new WMComponentBuilder();}//同WMComponent.Builder一样直接new了一个对象返回因为其生命周期为//SysUISingletonOverridepublic SysUIComponent.Builder getSysUIComponent() {return new SysUIComponentBuilder();}//对GlobalRootComponent的接口方法的实现。在实现中使用了ThreadFactoryImpl_Factory类来//实例化对象//这里可能就会有以问题了为何不是直接new一个对象反而用了ThreadFactoryImpl_Factory来实例化//因为在GlobalConcurrencyModule里面有如下的绑定关系//Binds//public abstract ThreadFactory bindExecutorFactory(ThreadFactoryImpl impl)//在需要ThreadFactory的时候就会创建ThreadFactoryImpl实例。而ThreadFactoryImpl实例//则由//其对应的工厂类(ThreadFactoryImpl_Factory)来创建Overridepublic ThreadFactory createThreadFactory() {return ThreadFactoryImpl_Factory.newInstance();}//返回一个为空的Optionalprivate static T ProviderOptionalT absentJdkOptionalProvider() {SuppressWarnings(unchecked) // safe covariant castProviderOptionalT provider (ProviderOptionalT) ABSENT_JDK_OPTIONAL_PROVIDER;return provider;}//使用Provider包装一个非空的Optional所有操作最后都会调用到其内部的delegateprivate static final class PresentJdkOptionalInstanceProviderT implements ProviderOptionalT {}//暂时未知private static final class PresentJdkOptionalLazyProviderT implements ProviderOptionalLazyT {}//实现Builder接口//各个接口只是简单的setterprivate static final class Builder implements GlobalRootComponent.Builder {}//实现接口private final class WMComponentBuilder implements WMComponent.Builder {}//实现子组件,只要是其子组件就在内部实现一个非静态的类因为subcomponent含有//component的所有依赖关系因此需要实现为一个内部类这样它就会持有一个对外部类的引用//同理WMComponentImpl的subcomponent也会在其内部出现private final class WMComponentImpl implements WMComponent {}//实现Builderprivate final class SysUIComponentBuilder implements SysUIComponent.Builder {}//实现子组件private final class SysUIComponentImpl implements SysUIComponent {} }在对GlobalRootImpl接口的实现中分别完成了如下的工作 根据Dagger2中的图实现对应的构造函数根据Dagger2中的图实现对应的接口方法对subcomponent将其实现为内部类对各个Builder接口进行实现 从上我们也可以看到其和我们的Demo模板的生产差异不大只是体量变大了很多 接下来看看WMComponent的实现 WMComponent WMComponent的定义如下 WMSingleton Subcomponent(modules {WMShellModule.class}) public interface WMComponent {//Subcomponent.Builder定义了Builder接口//在上面已经看到了WMComponent.Builder的接口实现了Subcomponent.Builderinterface Builder {WMComponent build();}//默认方法用来初始化整个Shell.此处可以暂时不用管Shell对应的逻辑语义//实际上你可以将其理解为对WindowManager的部分功能的封装并提供接口让用户与WM可以交互//犹如Bash shell(Bourne-Again Shell)在OS中的作用default void init() {getShellInit().init();}//用来获取ShellInit的实现它只会在上面的init函数中被调用//ShellInit的抽象表示对Shell进行初始化的一个入口点。WMSingletonShellInit getShellInit();//返回一个OptionalShellCommandHandler对象WMSingletonOptionalShellCommandHandler getShellCommandHandler();//省略类似部分 }在上面的图中我们“绘制”了WMComponent的Builder接口同时还绘制了可以获取ShellInit的接口。 在查看Dagger2生成的代码之前我们看看我们是怎么绘制图让Dagger2来生成ShellInit的。 再次注意ShellInit的抽象表示的是WMShell的一个入口对象。 从上面的代码可以知道WMComponent的模块有WMShellModule。直接搜寻其源码查看是否有ShellInit的返回,发现并没有。但是WMShellModule的还包含一个WMShellBaseModule在其中可以搜寻到ShellInit的返回。如下 WMShellBaseModule WMShellBaseModuel告诉了Dagger2如何创建ShellInit对象如下 Module public abstract class WMShellBaseModule{//省略部分代码//通过Provides告诉Dagger2当需要ShellInit的时候将会调用本函数//即返回ShellInitImpl的asShellInit()方法//而ShellInitImpl的对象则通过下一个方法进行提供WMSingletonProvidesstatic ShellInit provideShellInit(ShellInitImpl impl) {return impl.asShellInit();}//告诉Dagger2如果需要ShellInitImpl对象的时候则由本方法提供//在本方法中通过new一个ShellInitImpl对象来创建对应的ShellInitImplWMSingletonProvidesstatic ShellInitImpl provideShellInitImpl(DisplayImeController displayImeController,DragAndDropController dragAndDropController,ShellTaskOrganizer shellTaskOrganizer,OptionalBubbleController bubblesOptional,OptionalLegacySplitScreenController legacySplitScreenOptional,OptionalSplitScreenController splitScreenOptional,OptionalAppPairsController appPairsOptional,OptionalPipTouchHandler pipTouchHandlerOptional,FullscreenTaskListener fullscreenTaskListener,Transitions transitions,StartingWindowController startingWindow,ShellMainThread ShellExecutor mainExecutor) {return new ShellInitImpl(displayImeController,dragAndDropController,shellTaskOrganizer,bubblesOptional,legacySplitScreenOptional,splitScreenOptional,appPairsOptional,pipTouchHandlerOptional,fullscreenTaskListener,transitions,startingWindow,mainExecutor);} }从上面的代码可以知道WMShell的初始化入口点是ShellInitImpl的asShellInit()方法返回的对象.至于该对象内部是如何进行初始化的会在合适的时候介绍到现在我们专注于WMComponent的各种初始化上 同理对WMComponent中的其他接口方法实现细节类似。 接下来看看Dagger2对WMComponenet相关代码的实现。首先是其Builder的实现 Dagger2生成的WMComponent.Builder 在前文中的GlobalRootComponent的实现中我们看到了WMComponent.Builder的实现现将其内容展现如下 public final class DaggerGlobalRootComponent implements GlobalRootComponent{//省略部分代码private final class WMComponentBuilder implements WMComponent.Builder{Overridepublic WMComponent build(){//直接new一个WMComponentImpl,这个对象是对WMComponent接口的实现return new WMComponentImpl();}}//省略部分代码 }接下来看看Dagger2对WMComponent接口的实现。 Dagger2生成的WMComponent WMComponent作为GlobalRootComponent的subcomponent则WMComponent被放置在了DaggerGlobalRootComponent的内部如下 public final class DaggerGlobalRootComponent implements GlobalRootComponent{//省略部分代码private final class WMComponentImpl implements WMComponent {//同component一样将成员定义成Provider的封装//只要在需要的时候才通过其ProviderT.get()方法获取其内部的实现private ProviderHandler provideShellMainHandlerProvider;//省略相似代码//生成的构造函数通过调用initialize()方法进行初始化private WMComponentImpl() {initialize();}//对内部的成员进行初始化SuppressWarnings(unchecked)private void initialize() {//Dagger2自动找到需要的依赖然后对本对象的成员进行赋值初始化操作}//实现其对应的接口Overridepublic ShellInit getShellInit() {return provideShellInitProvider.get();}//省略其他相似代码}//省略部分代码 }从上面生成的代码中我们看一看到WMComponent这个subcomponent 几乎和GlobalRootComponent的结构一致。 而这些生成内的东西现在不需要关系我们只需要知道其结构和大体抽象代码在真正的业务实现细节中会在有需要的地方进行提及。 再次提醒WMComponent为Window Manager提供给SystemUI的交互接口。现在只需知道这一层抽象意义即可 接下来继续看看SysUIComponent. SysUIComponent 先看看源码中是如何定义SysUIComponent的即我们如何绘制SysUIComponent的如下 SysUISingleton Subcomponent(modules {DefaultComponentBinder.class,DependencyProvider.class,SystemUIBinder.class,SystemUIModule.class,SystemUIDefaultModule.class}) public interface SysUIComponent {//又来Builder模式//并传递WMComponent中相应的组件给SysUIComponent//正是基于此WMComponent组件的初始化必须在SysUIComponent组件之前完成//且可以通过提供Optional?.empty()来替换其中的组件这也是SystemUIFactory中的init()//函数中的部分代码SysUISingletonSubcomponent.Builderinterface Builder {//绑定实例内容如前文,对应的语义见上一篇博文http://t.csdn.cn/4LyLqBindsInstanceBuilder setPip(OptionalPip p);//省略一些相似代码//build函数返回SysUIComponent接口的实现//其实仔细看过前面的WMComponent就会知道返回的实例多半叫做SysUIComponentImplSysUIComponent build();}//默认的初始化操作为了保持跟WMComponent一致的操作步调这里依然有一个init()接口//但是它的函数体为空default void init() {// Do nothing}//返回一个BootCompleteCacheImpl对象//这个对象我们在前一篇博文http://t.csdn.cn/4LyLq中介绍过用于缓存是否所有的//SystemUI服务都已经启动完成//其实这里读者可以思考一下是否BootCompleteCacheImpl对象还会再需要如果不需要了//它能被GC回收吗//如果不能回收是不是代表BootCompleteCacheImpl的生命周期不应该这样设置SysUISingletonBootCompleteCacheImpl provideBootCacheImpl();//返回一个Dependency对象//Dependency对象提供了SystemUI各个组件的快捷访问后文我们将会其进行详细介绍SysUISingletonDependency createDependency();//省略相同的代码//inject接口表示对PeopleProvider对象中注入被Inject标记的成员void inject(PeopleProvider peopleProvider); }其实有了上面的注释以及前面的模板读者应该已经知道了Dagger2对上面的一些生成代码了。 接下来我们会先看对应的Builder接口的生成然后再看SysUIComponent接口的生成 Dagger2生成的SysUIComponent.Builder SysUIComponent.Builder接口依然在DaggerGlobalRootComponent类中如下 private final class SysUIComponentBuilder implements SysUIComponent.Builder {//成员的定义省略//定义必要的成员用于在build阶段生成最终的SysUIComponentImpl//各种setter接口函数的实现用于保存传入的参数很简单省略//接口的build函数实现先检查然后new一个SysUIComponentImpl对象Overridepublic SysUIComponent build() {Preconditions.checkBuilderRequirement(setPip, Optional.class);Preconditions.checkBuilderRequirement(setLegacySplitScreen, Optional.class);Preconditions.checkBuilderRequirement(setSplitScreen, Optional.class);Preconditions.checkBuilderRequirement(setAppPairs, Optional.class);Preconditions.checkBuilderRequirement(setOneHanded, Optional.class);Preconditions.checkBuilderRequirement(setBubbles, Optional.class);Preconditions.checkBuilderRequirement(setTaskViewFactory, Optional.class);Preconditions.checkBuilderRequirement(setHideDisplayCutout, Optional.class);Preconditions.checkBuilderRequirement(setShellCommandHandler, Optional.class);Preconditions.checkBuilderRequirement(setTransitions, ShellTransitions.class);Preconditions.checkBuilderRequirement(setStartingSurface, Optional.class);Preconditions.checkBuilderRequirement(setTaskSurfaceHelper, Optional.class);return new SysUIComponentImpl(new DependencyProvider(), new NightDisplayListenerModule(), new UserModule(), setPip, setLegacySplitScreen, setSplitScreen, setAppPairs, setOneHanded, setBubbles, setTaskViewFactory, setHideDisplayCutout, setShellCommandHandler, setTransitions, setStartingSurface, setTaskSurfaceHelper);}}Builder函数的实现很是简单 保存必要的中间对象如各种OptionalTnew一个SysUIComponent接口的实现 接下来看看SysUIComponent的实现其实到这里大家已经非常熟悉了它的结构等同于GlbalRootComponent也等同于WMComponent Dagger2生成的SysUIComponent 作为GlobalRootComponent的subcomponent所以SysUIComponent的生成依然在DaggerGlobalRootComponent中如下 public final class DaggerGlobalRootComponent implements GlobalRootComponent {//省略不相干的部分private final class SysUIComponentImpl implements SysUIComponent {//省略成员定义其结构和内容相似于GlobalRootComponent和WMComponent,故不再啰嗦//对应的构造函数private SysUIComponentImpl(DependencyProvider dependencyProviderParam,NightDisplayListenerModule nightDisplayListenerModuleParam, UserModule userModuleParam,OptionalPip setPipParam, OptionalLegacySplitScreen setLegacySplitScreenParam,OptionalSplitScreen setSplitScreenParam, OptionalAppPairs setAppPairs,OptionalOneHanded setOneHandedParam, OptionalBubbles setBubblesParam,OptionalTaskViewFactory setTaskViewFactoryParam,OptionalHideDisplayCutout setHideDisplayCutoutParam,OptionalShellCommandHandler setShellCommandHandlerParam,ShellTransitions setTransitionsParam, OptionalStartingSurface setStartingSurfaceParam,OptionalTaskSurfaceHelper setTaskSurfaceHelper) {//因为成员函数过多因此分成了7个初始化辅助函数进行初始化}//initialize,initialize1,initialize2,initialize3,initialize4,initialize5,//initialize6//这几个函数都是用于初始化成员的其中初始化成员的方法和过程跟GlobalRootComponent//和WMComponent类似SuppressWarnings(unchecked)private void initialize()//实现的接口省略较简单//对PeopleProvider中被Inject标注的成员进行赋值Overridepublic void inject(PeopleProvider peopleProvider) {injectPeopleProvider(peopleProvider);}//使用辅助类 Type_MembersInjector。进行成员的赋值//PeopleProvider_MembersInjector.injectMPeopleSpaceWidgetManager()的实现就为//instance.mPeopleSpaceWidgetManager mPeopleSpaceWidget;private PeopleProvider injectPeopleProvider(PeopleProvider instance) {PeopleProvider_MembersInjector.injectMPeopleSpaceWidgetManager(instance, peopleSpaceWidgetManagerProvider.get());return instance;}//SysUIComponent的subcomponent的builder的实现private final class ExpandableNotificationRowComponentBuilder implements ExpandableNotificationRowComponent.Builder {}//SysUIComponent的subcomponent的实现private final class ExpandableNotificationRowComponentImpl implements ExpandableNotificationRowComponent {}//SysUIComponent的subcomponent的Factory的实现private final class KeyguardBouncerComponentFactory implements KeyguardBouncerComponent.Factory {}//SysUIComponent的subcomponent的实现private final class KeyguardBouncerComponentImpl implements KeyguardBouncerComponent {}//省略相似部分} }从上面的生成结果中我们可以看到SysUIComponent的生成跟GlobalRootComponent很是类似。主要完成 其内部subcomponent的Bulider的实现其内部subcomponent的Factory的实现其内部subcomponent的实现其内部接口方法的实现 有了上面的介绍现在基本上已经非常明确各个组件的初始化过程和内部实现细节了。 接下来还剩下最后一个Dependency的实现细节 Dependency Dependency对应的抽象是什么这里直接给出一个结论为了方便在各个模块中能够直接引用Dagger2中的依赖。举个例子如果我要通过SysUIComponent访问某个依赖则可能出现如下的调用情况 dsysuicomponent.getxxx().getxxx().getxxx().getxxx(); d.xxx();上面的代码中出现了多层的getxxx()函数因此为了方便将一些常见的依赖通过Dependency来调用即可。现在提供的方法为Dependency.get(依赖.class)从而获得对应的依赖 这也是这个类的名字的由来。 有了上面的观点就非常容易看懂Dependency.java文件了 如下 SysUISingleton public class Dependency {//一些简单的成员定义省略//由Dagger2进行创建Injectpublic Dependency() {}//初始化各个依赖protected void start() {//mProviders是一个以Object为对象以LazyDependencyCreator为值的Map//LazyDependencyCreator封装创建依赖的方法用于在需要的时候创建mProviders.put(TIME_TICK_HANDLER, mTimeTickHandler::get);//省略相似部分//将Dependency对象保存在Static字段中便于访问Dependency.setInstance(this);}//省略一些简单的函数//当访问某个具体的依赖时最终的访问点private synchronized T T getDependencyInner(Object key) {SuppressWarnings(unchecked)//1. 首先检查依赖的缓存中是否有对应的依赖其中缓存使用了ArrayMap进行存储(注意其和// HashMap之间的差别)//2. 如果没有调用createDependency创建T obj (T) mDependencies.get(key);if (obj null) {obj createDependency(key);//3. 如果创建完成就将其加入缓存中方便未来调用。注意此处有同步控制,防止并发// 带来的问题mDependencies.put(key, obj);//4. 如果某些依赖需要使用dump功能则将其注册到DumpManager。如同// SystemUIService中的初始化最后部分一样if (autoRegisterModulesForDump() obj instanceof Dumpable) {mDumpManager.registerDumpable(obj.getClass().getName(), (Dumpable) obj);}}return obj;}//创建依赖的具体实现VisibleForTestingpublic T T createDependency(Object cls) {//1. 检查参数必须是DependencyKey类型或者Class类型Preconditions.checkArgument(cls instanceof DependencyKey? || cls instanceof Class?);//2. 通过key得到LazyDependencyCreator对象。这个对象通常封装着一个用于创建具// 体对象的方法。如LazyT的get()方法SuppressWarnings(unchecked)LazyDependencyCreatorT provider mProviders.get(cls);if (provider null) {throw new IllegalArgumentException(Unsupported dependency cls . mProviders.size() providers known.);}//3. 调用封装的方法(如LazyT.get())创建具体的对象return provider.createDependency();}//定义延迟创建的一种封装形式private interface LazyDependencyCreatorT {T createDependency();}//对依赖的key的封装public static final class DependencyKeyV {private final String mDisplayName;public DependencyKey(String displayName) {mDisplayName displayName;}Overridepublic String toString() {return mDisplayName;}}//省略掉一些简单的代码 }从上面可以知道Dependency就做了两件事情 缓存需要用的依赖的LazyT封装缓存需要用的依赖的具体实例。然后在需要的时候通过get()函数即可得到相应的依赖 至此我们介绍了SystemUIFactory的init()方法中重要组件的创建和初始化细节。也完成了整个SystemUI的启动 现在将整个启动过程总结如下 system_server启动之后开始启动各种服务在启动其他服务的时候会先通过PackageManager获得要启动systemui的组件名字然后根据名字启动systemui组件在上面一步获得的名字就是SystemUIService。启动SystemUIService则会先创建SystemUIApplication在创建之前会先调用SystemUIAppComponentFactory添加相应的依赖注入SystemUIApplication创建之后通过调用SystemUIFactory.init() 方法初始化Dagger2中的依赖。(本文的内容)同时在SystemUIApplication中会监听系统的启动广播。接着创建SystemUIService,再创建之前还会先调用SystemUIAppComponentFactory相应的方法添加依赖注入创建SystemUIService之后通过SystemUIApplication启动各种服务 接下来我们将进入SystemUI的UI部分。看看状态栏是如何被加入整个屏幕的。然后一步步拆分查看下拉状态栏中的各个图标的实现 因为最近要上课尽量保持一周一更
http://www.dnsts.com.cn/news/147343.html

相关文章:

  • 中国建设学会查询网站电子商务网站设计代做
  • 素材网站推广方案玉树电子商务网站建设哪家好
  • 旅游网站建设规划报告怎么写私人定制app
  • 抽奖的网站怎么做的外贸公司代理
  • 用一个域名免费做网站房地产市场调查的途径有哪些
  • 网站建设费算办公费吗深圳商城网站设计多少钱
  • 模板网站建设公司上海网站建设搜q.479185700
  • 拖拽式建站南昌网站建设公务
  • 分享一个网站能用的c2c模式特点
  • 大连免费营销型建站网络推广wordpress幻灯片教程视频教程
  • 备案 网站名称 重复农大南路网络营销推广优化
  • 河北三河建设厅网站电商总监带你做网站策划
  • 网站建设 电子商务 品牌首选IDC地方网站域名选择
  • 网站建设的目的及目标建一个个人网站
  • 昆山规建设局网站html简单网页
  • 中企动力建设网站怎么样北京网站开发公司飞沐
  • 自己的网站怎么接广告wordpress文章图片加水印
  • 咸阳网站制作建设网站制作软件排名
  • 茶叶网站的建设策划书wordpress设置横向菜单
  • 镇江 网站建设肇庆企业网站建设
  • 爱站网关键词排名业之峰装饰官网
  • 制作短链接网站深圳龙岗今天新闻头条
  • 长春做网站搜吉网传媒苏州风光ix5
  • 单县建设局网站国内最好的分销平台
  • 商城网站建设新闻网络广告推广策划书
  • 会展官方网站建设如何建立公司的网站
  • 莱芜市莱城区城乡建设局网站部队网站建设多少钱
  • 公司网站建设需要什么iis7 伪静态 wordpress
  • golang 做网站伪静态 多个网站
  • 学习网站开发心得天津建设工程信息网账号密码