Análisis del código fuente de Android 12: capa de aplicación tres (SystemUIFactory y su análisis de dependencia)

Análisis del código fuente de Android 12: capa de aplicación tres (SystemUIFactory y su análisis de dependencia)

En el artículo anterior, se presentó el proceso de inicio de SystemUI y se mencionó brevemente a Dagger2 para administrar las dependencias utilizadas en cada SystemUI. Y esta parte del código está en: mContextAvailableCallback.onContextAvailable(this); proceso. Sólo tocamos brevemente esta parte del proceso sin analizarla en detalle.

A continuación, a partir de esta llamada, presentaremos la inicialización de componentes y subcomponentes en SystemUI y comprenderemos cómo utilizar estos componentes.

Este artículo primero utilizará un ejemplo para presentar brevemente las plantillas de generación para cada anotación en Dagger2, luego presentará el proceso de creación de componentes y subcomponentes importantes en SystemUI y finalmente hará la transición a una clase clave Dependencia

Nota: Aquí hay otro ejemplo para ilustrar la plantilla de generación de Dagger2, completamente porque Dagger2 genera demasiado código para SystemUI, lo que hace que no sea fácil de documentar.

Comprender las plantillas de Dagger2

Para comprender mejor la plantilla generada por el código de Dagger2, escribimos de acuerdo con el siguiente ejemplo y luego vemos las clases generadas.

Coloque el siguiente código en un archivo 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.Factory
    interface Factory {
    
    
        DemoSubComponent1 create();
    }

    DemoAClass getAClass();

    void inject(DemoInject inject);

    //SubComponent1隶属于的模块
    //指定了DemoInterface 和DemoBinds之间的关系,当需要DemoInterface的时候,
    //  Dagger2会创建对应的DemoBinds对象
    @Module(subcomponents = DemoSubComponent1.class)
    abstract class DemoModule1{
    
    
        @Binds
        abstract DemoInterface getInterface(DemoBinds bindings);
    }
}

//SubComponent2,提供一个功能
//    1. 获取DemoBClass对象
@Subcomponent
interface DemoSubComponent2{
    
    

    //为了和SubComponent1作区分,这里使用了Builder类来创建SubComponent2
    @Subcomponent.Builder
    interface Builder {
    
    
        DemoSubComponent2 build();
    }


    DemoBClass getBClass();

    //SubComponent2隶属的模块,该模块还提供了一个@Provides
    @Module(subcomponents = DemoSubComponent2.class)
    class DemoModule2{
    
    

        //当需要DemoProvider对象的时候,就会调用此方法
        @Provides
        DemoProvider getProvider(){
    
    
            return new DemoProvider();
        }
    }
}

//用于演示@Binds
interface DemoInterface{
    
    
    void test();
}

//用于演示@Binds
class DemoBinds implements DemoInterface{
    
    

    @Inject
    DemoBinds(){
    
    

    }

    @Override
    public void test() {
    
    

    }
}

//用于演示@Provides
class DemoProvider{
    
    

}

//用于演示,inject函数
class DemoInject{
    
    
    @Inject
    DemoAClass a;
}

//用于演示,生命周期
@SysUISingleton
class DemoAClass{
    
    
    @Inject
    public DemoAClass(){
    
    

    }
}

//用于演示返回的对象
class DemoBClass{
    
    
    @Inject
    public DemoBClass(){
    
    

    }
}

Con la imagen dibujada arriba, verifiquemos los archivos generados por Dagger2 según la imagen. Los archivos generados son:

  1. DagaDemoComponent.java
  2. DemoAClass_Factory.java
  3. DemoBClass_Factory.java
  4. DemoBinds_Factory.java
  5. DemoInject_MembersInjector.java
  6. DemoSubComponent2_DemoModule2_GetProviderFactory.java
  7. DemoSubComponent2_DemoModule2_Proxy.java

A continuación, verifiquemos los 7 archivos generados uno por uno, cuál es su contenido y las 6 clases restantes se usarán en DaggerDemoComponent.java. Por lo tanto, primero miramos las 6 clases restantes y finalmente miramos DaggerDemoFactory.java.

DemoAClass_Factory, DemoBClass_Factory, DemoBinds_Factory

El código fuente de DemoAClass_Factory es el siguiente:

//对于任何类来讲,只要其构造函数带有@Inject,则Dagger2都会创建一个对应的工厂类,
//叫做:XXX_Factory,它实现了Factory<T>接口
//欲使用这个工厂类,则调用create()方法,得到这个工厂类的实例,工厂类的实例永远只有一个
//欲使用这个工厂类产生的对象,则调用newInstance()方法,得到工厂类的产生对象,
//工厂类产生的对象可以有多个
public final class DemoAClass_Factory implements Factory<DemoAClass> {
    
    
  @Override
  public 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 son exactamente iguales que DemoAClass_Factory, sin más detalles.

DemoInject_MembersInjector

DemoInject_MembersInjector se utiliza para la inyección de miembros auxiliares, porque el siguiente código en la clase DemoInject

class DemoInject{
    
    
    @Inject
    DemoAClass a;
}

El código fuente completo de la clase auxiliar es el siguiente:


//每一个辅助注入的类,都是MembersInjector<T>的具体实现
//在实现中,对要注入的成员,使用Provider<T>表示,抽象为:T的提供者。它会在辅助类创建的时候被
//初始化好
//        对被注入的类,使用instance表示
//同工厂类一样,辅助注入类的实例化,也是通过create()方法进行
//同工厂类不一样的是,每次create,都会创建不同的辅助注入对象
//注入方式,则直接调用injectMembers()函数进行
public final class DemoInject_MembersInjector implements MembersInjector<DemoInject> {
    
    
  private final Provider<DemoAClass> aProvider;

  public DemoInject_MembersInjector(Provider<DemoAClass> aProvider) {
    
    
    this.aProvider = aProvider;
  }

  public static MembersInjector<DemoInject> create(Provider<DemoAClass> aProvider) {
    
    
    return new DemoInject_MembersInjector(aProvider);
  }

  @Override
  public 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;
  }
}

La clase de inyección auxiliar anterior también es muy simple, luego sigue leyendo

DemoSubComponent2_DemoModule2_GetProviderFactory

La clase DemoSubComponent2_DemoModule2_GetProviderFactory representa la clase de fábrica de implementación para @Provides. El código fuente es el siguiente:


//对于任何一个被@Provides标记的函数,Dagger2都会创建一个提供者工厂类,它实现了Factory<T>
//同DemoAClass工厂类一样,它也会有一个create()方法,用于实例化提供者工厂类
//不同之处在于,每次调用都会创建一个新的提供者工厂类

//只有需要提供者工厂类,生产提供者时,才会调用get()方法,用于返回生产出来的对象。

public final class DemoSubComponent2_DemoModule2_GetProviderFactory implements Factory<DemoProvider> {
    
    
  private final DemoSubComponent2.DemoModule2 module;

  public DemoSubComponent2_DemoModule2_GetProviderFactory(DemoSubComponent2.DemoModule2 module) {
    
    
    this.module = module;
  }

  @Override
  public 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());
  }
}

El código anterior sigue siendo muy simple y ya no es detallado.

DemoSubComponent2_DemoModule2_Proxy

DemoSubComponent2_DemoModule2_Proxy es una representación del módulo abstracto. El código fuente es el siguiente:

public final class DemoSubComponent2_DemoModule2_Proxy {
    
    
  private DemoSubComponent2_DemoModule2_Proxy() {
    
    
  }

  public static DemoSubComponent2.DemoModule2 newInstance() {
    
    
    return new DemoSubComponent2.DemoModule2();
  }
}

En DemoModule2, no hay lugar para implementar, y @Binds es semánticamente lo suficientemente obvio, por lo que la clase generada anteriormente no tiene lugares excesivos. más simple

A continuación, veamos cómo DaggerDemoComponent usa las clases creadas anteriormente para manejar las dependencias entre ellas.

DagaDemoComponente

DaggerDemoComponent es la entrada a toda la inyección de dependencia, su código fuente es el siguiente:

//实现我们的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类,用于创建subcomponent1
  @Override
  public DemoSubComponent1.Factory getSubComponent1Factory() {
    
    
    //见后文
    return new DemoSubComponent1Factory();
  }

  //返回subcomponent2的Bulder类,用于创建subcomponent2
  @Override
  public DemoSubComponent2.Builder getSubComponent2Builder() {
    
    
    return new DemoSubComponent2Builder();
  }

  //用于创建DaggerDemoComponent,在这个类中,只是简单的new了一个DaggerDemoComponent即可
  public static final class Builder {
    
    
    private Builder() {
    
    
    }

    
    @Deprecated
    public 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 {
    
    
    @Override
    public DemoSubComponent1 create() {
    
    
      //创建DemoSubComponent1的实例对象,并返回
      return new DemoSubComponent1Impl();
    }
  }

  //subcomponet1的具体实现
  private final class DemoSubComponent1Impl implements DemoSubComponent1 {
    
    
    private Provider<DemoAClass> 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的提供者,让其提供同一个对象
    @Override
    public DemoAClass getAClass() {
    
    
      return demoAClassProvider.get();
    }

    //向DemoInject中注入需要的成员
    @Override
    public 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 {
    
    
    @Override
    public DemoSubComponent2 build() {
    
    
      //创建subcomponent2对象,并直接返回
      return new DemoSubComponent2Impl();
    }
  }

  //subcomponent2的具体实现类
  private final class DemoSubComponent2Impl implements DemoSubComponent2 {
    
    

    //因为DemoSubComponent2和DemoBClass并不是同一生命周期,所以,每次都创建一个新的
    //DemoBClass对象返回
    //因此,也就不需要相应的提供者类,也就不需要相应的对提供者类进行初始化    
    private DemoSubComponent2Impl() {
    
    

    }

    @Override
    public DemoBClass getBClass() {
    
    
      return new DemoBClass();
    }
  }
}

El siguiente trabajo se completa en Componente:

  1. Componente implementado, subcomponente y sus correspondientes clases Builder y Factory. El subcomponente es la clase interna del componente.
  2. Implemente los métodos de interfaz correspondientes, estos métodos se delegarán a otras clases auxiliares xxx_Factory y xxxx_MembersInjector para completarlos.
  3. La clase de fábrica delegada xxx_Factory y la clase auxiliar xxx_MembersInjector se inicializarán correctamente.

En este punto, tenemos una comprensión general de la plantilla generada por Dagger2 y hemos hecho algunos comentarios sobre los detalles de implementación.

A continuación, sigamos analizando el proceso de creación de componentes importantes en SystemUI.

SystemUI es el punto de partida para crear dependencias de Dagger2

En el primer artículo, analizamos brevemente mContextAvailableCallback.onContextAvailable(this) en SystemUIApplication.onCreate().

Este es el punto de partida para que Dagger2 cree dependencias, la asignación de mContextAvailableCallback, en SystemUIAppComponentFactory.java.

como sigue:

@NonNull
@Override
//此函数在创建SystemUIApplication之前调用
public Application instantiateApplicationCompat(
        @NonNull ClassLoader cl, @NonNull String className)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    
    
    //调用父类方法,创建Application,此处的app实例为SystemUIApplication
    Application 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;
}

De lo anterior vimos que SystemUIFactory llama al método estático createFromConfig para crear. Puedes adivinar uno o dos por el nombre: Crear SystemUIFactory desde la configuración

Por desgracia, vale la pena pensar en esto, ¿por qué crearlo desde la configuración? ¿Se puede configurar como un SytemUIFactory diferente? ¿Hay alguna diferencia para cada SystemUIFactory?

Miremos hacia abajo con preguntas

SistemaUIFactory

Por el nombre, SystemUIFactory parece ser la clase de fábrica de SystemUI. En el artículo anterior Análisis del código fuente de Android 12: Capa de aplicación 2 (organización general y proceso de inicio de SystemUI): en la sección de componentes personalizados de http://t.csdn.cn/AuzsL , nuestro componente personalizado hereda SystemUI

¿Es SystemUIFactory su clase de fábrica?

Echemos un vistazo al código fuente. Para reducir la interferencia, comenzamos con el método createFromConfig en la sección anterior, de la siguiente manera

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);
    }
}

A continuación, continúe ingresando su función de inicialización, de la siguiente manera:

@VisibleForTesting
    public 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。在上一篇文章中已经提及过
        //这里就是去构建整个应用最最顶层的那个Component
        mRootComponent = buildGlobalRootComponent(context);
        //从GlobalRootComponent中,获取需要创建依赖的Builder。然后创建依赖

        //1. 先创建WmComponent (这是一个与SysUIComponent站在同一维度的Component,它负责提供WindowManager相关的东西,此处可不用太过在意,后面会详解)
        mWMComponent = mRootComponent.getWMComponentBuilder().build();
        if (mInitializeComponents) {
    
    
            //然后初始化
            mWMComponent.init();
        }

        //2. 再创建SysUIComponent
        SysUIComponent.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();
    }

En la función SystemUIFactory.init(), hay cuatro cosas principales:

  1. Crear e inicializar GlobalRootComponent
  2. Crear e inicializar WMComponent
  3. Crear e inicializar SysUIComponent
  4. Crear e inicializar dependencia

Estos cuatro objetos son los componentes que necesita toda la aplicación SystemUI. A través de estos cuatro componentes, puede obtener varias dependencias en Dagger2.

Antes de introducir estos 4 objetos uno a uno. Abordemos primero las preguntas anteriores, que incluyen:

  1. ¿Por qué se crea SystemUIFactory desde la configuración?
  2. ¿El nombre de SystemUIFactory te parece un poco extraño?

Responda la pregunta 1: debido a que SystemUIFactory no solo puede crear una instancia de SysetmUIFactory directamente, sino que a veces también necesita crear una instancia de subclases de SystemUIFactory (como TvSystemUIFactory), la razón por la que necesita un TvSystemUIFactory es porque requiere una versión diferente de GlobalRootComponent llamada TvGloabRootComponent. Y este TvGlobalRootComponent Heredado de GlobalRootComponent

Responda la pregunta 2: Obviamente, la creación de instancia proporcionada por SystemUIFactory debería llamarse GloablRootComponentFactory. No debería llamarse SystemUIFactory, creo que este también es un lugar donde los desarrolladores no son lo suficientemente rigurosos.
Por supuesto, puede haber otros significados que no he entendido.

En este punto, SystemUIFactory en realidad no tiene nada que presentar. El contenido restante no es más que captadores. El contenido es simple y se puede omitir aquí.

El siguiente es el proceso de creación de varios componentes.

Componente raíz global

La creación de GlobalRootComponent debe comenzar con su diagrama. En Análisis del código fuente de Android 12: Capa de aplicación 2 (Organización general y proceso de inicio de SystemUI): http://t.csdn.cn/AuzsL , definimos una interfaz Builder para GlobalRootComponent.

como sigue:

@Singleton
@Component(modules = {
    
    
        GlobalModule.class,
        SysUISubcomponentModule.class,
        WMModule.class})
public interface GlobalRootComponent {
    
    

    @Component.Builder
    interface Builder {
    
    
        @BindsInstance
        Builder context(Context context);

        GlobalRootComponent build();
    }

    //省略无关紧要部分
}

Entonces, ¿cómo genera Dagger2 este constructor?

GlobalRootComponent.Builder generado por Dagger2

Durante el proceso de compilación, Dagger2 implementará la interfaz Builder anterior y se generará una clase llamada Builder. Como sigue:
Esta clase está ubicada en:

out/soong/.intermediates/frameworks/base/packages/SystemUI/SystemUI-core/android_common/kapt/gen/sources/com/android/systemui/dagger/DaggerGlobalRootComponent.java
private static final class Builder implements GlobalRootComponent.Builder {
    
    
    private Context context;

    @Override
    public Builder context(Context context) {
    
    
      //1. 先判断传入的参数是否为空
      //2. 将传入的参数,赋值给内成员(这也是在上一篇文章中提及的BindsInstance的语义)
      this.context = Preconditions.checkNotNull(context);
      return this;
    }

    @Override
    public GlobalRootComponent build() {
    
    
      //1. 先判断context是否为空
      //2. new一个DaggerGlobalRootComponennt对象,该对象就是Dagger2中实现
      //	GlobalRootComponent接口的对象
      Preconditions.checkBuilderRequirement(context, Context.class);
      return new DaggerGlobalRootComponent(new GlobalModule(), context);
    }
  }

A continuación, veamos los detalles de implementación del GlobalRootComponent de Dagger2.

GlobalRootComponent generado por Dagger2

Los archivos generados se encuentran en:

out/soong/.intermediates/frameworks/base/packages/SystemUI/SystemUI-core/android_common/kapt/gen/sources/com/android/systemui/dagger/DaggerGlobalRootComponent.java

Hay mucho contenido. Para simplificar el análisis, sangraré parte del código y simplificaré los detalles de implementación, porque su implementación es casi la misma que la plantilla presentada anteriormente, y ahora solo necesitamos comprender su estructura.

public final class DaggerGlobalRootComponent implements GlobalRootComponent {
    
    
  
    //定义一个成员变量,类型为Provider<T> 它可以通过
    //Provider<T>.get() 得到对应的具体的对象
    //正是这个get()函数,可以让成员真正被需要的时候才初始化
    //这样可以减少内存的使用
    //可将其理解为:Context的提供者(同前面的模板一起理解,几乎可以肯定,它的实现为
    //							DoubleCheck类)
    private Provider<Context> 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方法的工厂类,它实现了Factory<T>接口
    return FrameworkServicesModule_ProvideResourcesFactory.provideResources(context);
  }

  //同MainResources()函数一样,Dagger2自动处理好其调用
  private Executor mainExecutor() {
    
    
    return GlobalConcurrencyModule_ProvideMainExecutorFactory.provideMainExecutor(context);
  }

  //这个是实现的GlobalRootComponent的接口.在这个接口中,直接new了一个对象并返回
  //倘若每次调用这个方法,则会创建不同的对象。这是因为他们的生命周期不一样
  //GlobalRootComponent的生命周期为@SingleTton
  //而WMComponent.Builder的生命周期为@WMSingleton
  @Override
  public WMComponent.Builder getWMComponentBuilder() {
    
    
    return new WMComponentBuilder();
  }

  //同WMComponent.Builder一样,直接new了一个对象返回,因为其生命周期为
  //@SysUISingleton
  @Override
  public 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)来创建
  @Override
  public ThreadFactory createThreadFactory() {
    
    
    return ThreadFactoryImpl_Factory.newInstance();
  }

  //返回一个为空的Optional
  private static <T> Provider<Optional<T>> absentJdkOptionalProvider() {
    
    
    @SuppressWarnings("unchecked") // safe covariant cast
    Provider<Optional<T>> provider = (Provider<Optional<T>>) ABSENT_JDK_OPTIONAL_PROVIDER;return provider;
  }

  //使用Provider包装一个非空的Optional,所有操作最后都会调用到其内部的delegate
  private static final class PresentJdkOptionalInstanceProvider<T> implements Provider<Optional<T>> {
    
    }

  //暂时未知
  private static final class PresentJdkOptionalLazyProvider<T> implements Provider<Optional<Lazy<T>>> {
    
    }

  //实现Builder接口
  //各个接口,只是简单的setter
  private static final class Builder implements GlobalRootComponent.Builder {
    
    }

  //实现接口
  private final class WMComponentBuilder implements WMComponent.Builder {
    
    }

  //实现子组件,只要是其子组件,就在内部实现一个非静态的类,因为subcomponent含有
  //component的所有依赖关系,因此需要实现为一个内部类,这样它就会持有一个对外部类的引用
  //同理,WMComponentImpl的subcomponent也会在其内部出现
  private final class WMComponentImpl implements WMComponent {
    
    }

  //实现Builder
  private final class SysUIComponentBuilder implements SysUIComponent.Builder {
    
    }

  //实现子组件
  private final class SysUIComponentImpl implements SysUIComponent {
    
    }
}

En la implementación de la interfaz GlobalRootImpl, se han completado las siguientes tareas:

  1. Implemente el constructor correspondiente según el gráfico en Dagger2
  2. Implemente el método de interfaz correspondiente según el diagrama en Dagger2
  3. Para el subcomponente, impleméntelo como una clase interna.
  4. Implementar cada interfaz de Builder

También podemos ver en lo anterior que no hay mucha diferencia entre su producción y nuestra plantilla de demostración, excepto que el volumen se ha vuelto mucho mayor.

A continuación, observe la implementación de WMComponent.

Componente WM

WMComponent se define de la siguiente manera

@WMSingleton
@Subcomponent(modules = {
    
    WMShellModule.class})
public interface WMComponent {
    
    

    //@Subcomponent.Builder定义了Builder接口
    //在上面,已经看到了WMComponent.Builder的接口实现了
    @Subcomponent.Builder
    interface Builder {
    
    
        WMComponent build();
    }

    //默认方法,用来初始化整个Shell.此处可以暂时不用管Shell对应的逻辑语义
    //实际上,你可以将其理解为对WindowManager的部分功能的封装并提供接口让用户与WM可以交互
    //犹如Bash shell(Bourne-Again Shell)在OS中的作用
    default void init() {
    
    
        getShellInit().init();
    }

    //用来获取ShellInit的实现,它只会在上面的init函数中被调用
    //ShellInit的抽象:表示对Shell进行初始化的一个入口点。
    @WMSingleton
    ShellInit getShellInit();

    //返回一个Optional<ShellCommandHandler>对象
    @WMSingleton
    Optional<ShellCommandHandler> getShellCommandHandler();

    //省略类似部分
}

En la figura anterior, "dibujamos" la interfaz Builder de WMComponent y también dibujamos la interfaz que puede obtener ShellInit.

Antes de mirar el código generado por Dagger2, echemos un vistazo a cómo dibujamos el diagrama y dejamos que Dagger2 genere ShellInit.

Tenga en cuenta nuevamente: la representación abstracta de ShellInit es un objeto de entrada de WMShell.

Del código anterior, podemos saber que el módulo de WMComponent tiene WMShellModule. Busque directamente su código fuente para ver si hay un retorno de ShellInit y descubra que no. Pero WMShellModule también contiene un WMShellBaseModule en el que se puede buscar el retorno de ShellInit. como sigue

Módulo WMShellBase

WMShellBaseModuel le dice a Dagger2 cómo crear un objeto ShellInit, de la siguiente manera

@Module
public abstract class WMShellBaseModule{
    
    

    //省略部分代码

    //通过@Provides告诉Dagger2,当需要ShellInit的时候,将会调用本函数
    //即返回ShellInitImpl的asShellInit()方法
    //而ShellInitImpl的对象,则通过下一个方法进行提供
    @WMSingleton
    @Provides
    static ShellInit provideShellInit(ShellInitImpl impl) {
    
    
        return impl.asShellInit();
    }

    //告诉Dagger2如果需要ShellInitImpl对象的时候,则由本方法提供
    //在本方法中,通过new一个ShellInitImpl对象来创建对应的ShellInitImpl
    @WMSingleton
    @Provides
    static ShellInitImpl provideShellInitImpl(DisplayImeController displayImeController,
            DragAndDropController dragAndDropController,
            ShellTaskOrganizer shellTaskOrganizer,
            Optional<BubbleController> bubblesOptional,
            Optional<LegacySplitScreenController> legacySplitScreenOptional,
            Optional<SplitScreenController> splitScreenOptional,
            Optional<AppPairsController> appPairsOptional,
            Optional<PipTouchHandler> 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);
    }
}

Del código anterior, podemos saber que el punto de entrada de inicialización de WMShell es el objeto devuelto por el método asShellInit() de ShellInitImpl. En cuanto a cómo se inicializa el objeto internamente, se introducirá en el momento adecuado. Ahora nos centraremos en varios componentes de WMShell. En la inicialización

De manera similar, para otros métodos de interfaz en WMComponent, los detalles de implementación son similares.

A continuación, echemos un vistazo a la implementación de Dagger2 del código relacionado con WMComponenet. El primero es la implementación de su Builder.

WMComponent.Builder generado por Dagger2

En la implementación anterior de GlobalRootComponent, vimos la implementación de WMComponent.Builder y su contenido ahora se muestra de la siguiente manera:

public final class DaggerGlobalRootComponent implements GlobalRootComponent{
    
    

  //省略部分代码

  private final class WMComponentBuilder implements WMComponent.Builder{
    
    
    @Override
    public WMComponent build(){
    
    
      //直接new一个WMComponentImpl,这个对象是对WMComponent接口的实现
      return new WMComponentImpl();
    }
  }

  //省略部分代码
}

Echemos un vistazo a la implementación de Dagger2 de la interfaz WMComponent.

WMConent generado por Dagger2

Como subcomponente de GlobalRootComponent, WMComponent se coloca dentro de DaggerGlobalRootComponent, de la siguiente manera:

public final class DaggerGlobalRootComponent implements GlobalRootComponent{
    
    

  //省略部分代码

    private final class WMComponentImpl implements WMComponent {
    
    

      //同component一样,将成员定义成Provider的封装
      //只要在需要的时候才通过其Provider<T>.get()方法获取其内部的实现
      private Provider<Handler> provideShellMainHandlerProvider;

      //省略相似代码

      //生成的构造函数,通过调用initialize()方法进行初始化
      private WMComponentImpl() {
    
    

        initialize();
      }

      //对内部的成员进行初始化
      @SuppressWarnings("unchecked")
      private void initialize() {
    
    
        //Dagger2自动找到需要的依赖,然后对本对象的成员,进行赋值初始化操作
      }

      //实现其对应的接口
      @Override
      public ShellInit getShellInit() {
    
    
        return provideShellInitProvider.get();
      }

      //省略其他相似代码
    }
  //省略部分代码
}

Del código generado anteriormente, podemos ver que el subcomponente WMComponent tiene casi la misma estructura que GlobalRootComponent.

Y estas cosas generadas no necesitan estar relacionadas ahora, solo necesitamos conocer su estructura y código abstracto general, y en los detalles de implementación comercial real, se mencionarán cuando sea necesario.

Recordatorio nuevamente: WMComponent es la interfaz interactiva proporcionada por Window Manager a SystemUI. Ahora sólo te falta conocer este significado abstracto.

A continuación, continúe mirando SysUIComponent.

Componente SysUI

Primero veamos cómo se define SysUIComponent en el código fuente, es decir, cómo dibujamos SysUIComponent, de la siguiente manera:


@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()
    //函数中的部分代码
    @SysUISingleton
    @Subcomponent.Builder
    interface Builder {
    
    
      //绑定实例,内容如前文,对应的语义见上一篇博文<http://t.csdn.cn/4LyLq>
        @BindsInstance
        Builder setPip(Optional<Pip> p);
        //省略一些相似代码

        //build函数,返回SysUIComponent接口的实现
        //其实,仔细看过前面的WMComponent就会知道,返回的实例多半叫做SysUIComponentImpl
        SysUIComponent build();
    }

    //默认的初始化操作,为了保持跟WMComponent一致的操作步调,这里依然有一个init()接口
    //但是它的函数体为空
    default void init() {
    
    
        // Do nothing
    }

    //返回一个BootCompleteCacheImpl对象
    //这个对象,我们在前一篇博文<http://t.csdn.cn/4LyLq>中介绍过,用于缓存是否所有的
    //SystemUI服务都已经启动完成
    
    //其实,这里读者可以思考一下,是否BootCompleteCacheImpl对象还会再需要?如果不需要了,
    //它能被GC回收吗?
    
    //如果不能回收,是不是代表BootCompleteCacheImpl的生命周期不应该这样设置?
    @SysUISingleton
    BootCompleteCacheImpl provideBootCacheImpl();

   //返回一个Dependency对象
   //Dependency对象,提供了SystemUI各个组件的快捷访问,后文我们将会其进行详细介绍
    @SysUISingleton
    Dependency createDependency();

   //省略相同的代码
  
    //inject接口,表示对PeopleProvider对象中,注入被@Inject标记的成员
    void inject(PeopleProvider peopleProvider);
}

De hecho, con los comentarios anteriores y la plantilla anterior, los lectores ya deberían conocer algunos de los códigos generados anteriormente por Dagger2.

A continuación, primero veremos la generación de la interfaz Builder correspondiente y luego veremos la generación de la interfaz SysUIComponent.

SysUIComponent.Builder generado por Dagger2

La interfaz SysUIComponent.Builder todavía está en la clase DaggerGlobalRootComponent, de la siguiente manera:

private final class SysUIComponentBuilder implements SysUIComponent.Builder {
    
    
    
    //成员的定义,省略
    //定义必要的成员,用于在build阶段生成最终的SysUIComponentImpl

    //各种setter接口函数的实现,用于保存传入的参数,很简单,省略

    //接口的build函数实现,先检查,然后new一个SysUIComponentImpl对象
    @Override
    public 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);
    }
  }

La implementación de la función Builder es muy sencilla.

  1. Guarde los objetos intermedios necesarios, como varios Opcional<T>
  2. nuevoUna implementación de la interfaz SysUIComponent

A continuación, echemos un vistazo a la implementación de SysUIComponent, de hecho, todos están muy familiarizados con él aquí, su estructura es equivalente a GlbalRootComponent y WMComponent.

SysUIComponente generado por Dagger2

Como subcomponente de GlobalRootComponent, la generación de SysUIComponent todavía está en DaggerGlobalRootComponent, de la siguiente manera

public final class DaggerGlobalRootComponent implements GlobalRootComponent {
    
    

  //省略不相干的部分

  private final class SysUIComponentImpl implements SysUIComponent {
    
    
    
    //省略成员定义,其结构和内容,相似于GlobalRootComponent和WMComponent,故不再啰嗦

    //对应的构造函数
    private SysUIComponentImpl(DependencyProvider dependencyProviderParam,
        NightDisplayListenerModule nightDisplayListenerModuleParam, UserModule userModuleParam,
        Optional<Pip> setPipParam, Optional<LegacySplitScreen> setLegacySplitScreenParam,
        Optional<SplitScreen> setSplitScreenParam, Optional<AppPairs> setAppPairs,
        Optional<OneHanded> setOneHandedParam, Optional<Bubbles> setBubblesParam,
        Optional<TaskViewFactory> setTaskViewFactoryParam,
        Optional<HideDisplayCutout> setHideDisplayCutoutParam,
        Optional<ShellCommandHandler> setShellCommandHandlerParam,
        ShellTransitions setTransitionsParam, Optional<StartingSurface> setStartingSurfaceParam,
        Optional<TaskSurfaceHelper> setTaskSurfaceHelper) {
    
    
        //因为成员函数过多,因此分成了7个初始化辅助函数进行初始化
    }

    //initialize,initialize1,initialize2,initialize3,initialize4,initialize5,
    //initialize6
    //这几个函数都是用于初始化成员的,其中初始化成员的方法和过程,跟GlobalRootComponent
    //和WMComponent类似
    @SuppressWarnings("unchecked")
    private void initialize()
        

    //实现的接口,省略,较简单


    //对PeopleProvider中被@Inject标注的成员,进行赋值
    @Override
    public 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 {
    
    }

    //省略相似部分
  }
}

De los resultados de la generación anterior, podemos ver que la generación de SysUIComponent es muy similar a GlobalRootComponent. Finalización principal:

  1. Implementación de Bulider de su subcomponente interno
  2. La implementación de su subcomponente interno Factory.
  3. La implementación de su subcomponente interno.
  4. Implementación de sus métodos de interfaz interna.

Con la introducción anterior, ahora queda básicamente muy claro el proceso de inicialización y los detalles de implementación interna de cada componente.

A continuación, queda un último detalle de implementación de Dependencia.

Dependencia

¿Cuál es la abstracción correspondiente a Dependencia? Aquí se da directamente una conclusión: por conveniencia, se puede hacer referencia directamente a las dependencias en Dagger2 en cada módulo. Por ejemplo, si quiero acceder a una determinada dependencia a través de SysUIComponent, pueden ocurrir las siguientes llamadas:

d=sysuicomponent.getxxx().getxxx().getxxx().getxxx();
d.xxx();

En el código anterior, hay varias capas de funciones getxxx (), por lo que, por conveniencia, algunas dependencias comunes se pueden llamar a través de Dependencia. El método proporcionado ahora es: Dependency.get (Dependency.class) para obtener la dependencia correspondiente

Este es también el origen del nombre de esta clase.

Desde el punto de vista anterior, es muy fácil entender el archivo Dependency.java.

como sigue:

@SysUISingleton
public class Dependency {
    
    
    
    //一些简单的成员定义,省略

    //由Dagger2进行创建
    @Inject
    public 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;
    }

    //创建依赖的具体实现
    @VisibleForTesting
    public <T> T createDependency(Object cls) {
    
    
      //1. 检查参数,必须是DependencyKey类型或者Class类型
        Preconditions.checkArgument(cls instanceof DependencyKey<?> || cls instanceof Class<?>);

        //2. 通过key,得到LazyDependencyCreator对象。这个对象通常封装着一个用于创建具
        //	体对象的方法。如Lazy<T>的get()方法
        @SuppressWarnings("unchecked")
        LazyDependencyCreator<T> provider = mProviders.get(cls);
        if (provider == null) {
    
    
            throw new IllegalArgumentException("Unsupported dependency " + cls
                    + ". " + mProviders.size() + " providers known.");
        }
        //3. 调用封装的方法(如Lazy<T>.get()),创建具体的对象
        return provider.createDependency();
    }

    //定义延迟创建的一种封装形式
    private interface LazyDependencyCreator<T> {
    
    
        T createDependency();
    }

    //对依赖的key的封装
    public static final class DependencyKey<V> {
    
    
        private final String mDisplayName;

        public DependencyKey(String displayName) {
    
    
            mDisplayName = displayName;
        }

        @Override
        public String toString() {
    
    
            return mDisplayName;
        }
    }

    //省略掉一些简单的代码
}

Como puede ver en lo anterior, la dependencia hace dos cosas:

  1. El caché necesita usar el paquete de dependencias Lazy<T>
  2. Instancias concretas de dependencias necesarias para el almacenamiento en caché.
  3. Luego, cuando sea necesario, puede obtener las dependencias correspondientes a través de la función get().

Hasta ahora, hemos introducido los detalles de la creación e inicialización de componentes importantes en el método init() de SystemUIFactory. También se completa el inicio de todo SystemUI.

Ahora todo el proceso de inicio se resume de la siguiente manera:

  1. Después de que se inicia system_server, comienza a iniciar varios servicios.
  2. Al iniciar otros servicios, primero obtendrá el nombre del componente para iniciar systemui a través de PackageManager y luego iniciará el componente systemui de acuerdo con el nombre.
  3. El nombre obtenido en el paso anterior es SystemUIService.
  4. Cuando se inicia SystemUIService, SystemUIApplication se creará primero y se llamará a SystemUIAppComponentFactory para agregar la inyección de dependencia correspondiente antes de la creación.
  5. Después de crear SystemUIApplication, las dependencias en Dagger2 se inicializan llamando al método SystemUIFactory.init().(contenido de este artículo)
  6. Al mismo tiempo, la transmisión de inicio del sistema se monitoreará en SystemUIApplication.
  7. Luego cree SystemUIService, antes de crearlo, se llamará al método correspondiente de SystemUIAppComponentFactory para agregar inyección de dependencia.
  8. Después de crear SystemUIService, inicie varios servicios a través de SystemUIApplication

A continuación, ingresaremos a la parte UI de SystemUI. Vea cómo la barra de estado se agrega a toda la pantalla. Luego divídalo paso a paso para ver la implementación de cada ícono en la barra de estado desplegable

Como tengo que ir a clase recientemente, haré todo lo posible para actualizar una vez a la semana.

Supongo que te gusta

Origin blog.csdn.net/xiaowanbiao123/article/details/132563581
Recomendado
Clasificación