Manifest入口

<applicationandroid:name=".SystemUIApplication"... ...android:appComponentFactory=".SystemUIAppComponentFactory">... ...
</application>

在frameworks/base/packages/SystemUI路径下的AndroidManifest.xml中,application标签下appComponentFactory属性为".SystemUIAppComponentFactory"。PMS会将该属性解析至appInfo.appComponentFactory中。

SystemUIApplication加载

接下来我们看一下xml中配置的这个".SystemUIAppComponentFactory"是如何加载的。

首先,在ActivityThread.java中会调用handleBindApplication()

private void handleBindApplication(AppBindData data) {... ...Application app;app = data.info.makeApplication(data.restrictedBackupMode, null);try {mInstrumentation.callApplicationOnCreate(app); //注意这里会触发onCreate()} catch (Exception e) {... ...}
}

该方法中首先调用了makeApplication(),然后触发了application的onCreate()。

makeApplication()源码:

//该方法在LoadedApk.java类中
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {... ...Application app = null;String appClass = mApplicationInfo.className;try {... ...app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);    //调用newApplication()方法}... ...return app;
}

makeApplication中调用了Instrumentation.java类中的newApplication()方法。

newApplication()源码:

public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException, ClassNotFoundException {Application app = getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context);return app;
}

getFactory返回的是AppComponentFactory实例。由于SystemUIAppComponentFactory继承的是androidx中的AppComponentFactory,所以上面newApplication()方法中的instantiateApplication()会调用instantiateApplicationCompat()。

SystemUIAppComponentFactory类中重写instantiateApplicationCompat()方法:

注:该方法中注册了一个ContextAvailableCallback回调,该回调会在SystemUIApplication的onCreate()中被调用。

import androidx.core.app.AppComponentFactory;
public class SystemUIAppComponentFactory extends AppComponentFactory {... ...@NonNull@Overridepublic Application instantiateApplicationCompat(@NonNull ClassLoader cl, @NonNull String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {Application app = super.instantiateApplicationCompat(cl, className);if (app instanceof ContextInitializer) {((ContextInitializer) app).setContextAvailableCallback( // 注意这里注册了一个回调context -> {SystemUIFactory.createFromConfig(context);SystemUIFactory.getInstance().getRootComponent().inject(SystemUIAppComponentFactory.this);});}return app;}... ...
}

anroidx的AppComponentFactory中的instantiateApplication()方法:

//androidx.core.app.AppComponentFactory
public class AppComponentFactory extends android.app.AppComponentFactory {... .../*** @see #instantiateApplicationCompat*/@Overridepublic final Application instantiateApplication(ClassLoader cl, String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {return checkCompatWrapper(instantiateApplicationCompat(cl, className)); //调用instantiateApplicationCompat()}public @NonNull Application instantiateApplicationCompat(@NonNull ClassLoader cl,@NonNull String className)throws InstantiationException, IllegalAccessException, ClassNotFoundException {try {return (Application) cl.loadClass(className).getDeclaredConstructor().newInstance();} catch (InvocationTargetException | NoSuchMethodException e) {throw new RuntimeException("Couldn't call constructor", e);}}... ...}

在instantiateApplicationCompat()方法中,通过反射加载了SystemUIApplication。

至此,SystemUIApplication启动完成。

拓展:

SystemUIApplication.java源码:

public class SystemUIApplication extends Application implementsSystemUIAppComponentFactory.ContextInitializer {... ...private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;@Overridepublic void onCreate() {... ...mContextAvailableCallback.onContextAvailable(this);    //注意这里调用了ContextAvailable回调... ...}@Override//该方法刚才在AppComponentFactory中重写的instantiateApplicationCompat()中被调用public void setContextAvailableCallback(SystemUIAppComponentFactory.ContextAvailableCallback callback) {mContextAvailableCallback = callback;}... ...}

在onCreate()中调用了刚才注册的回调,我们再来看一下注册回调时候做了哪些事情:

1、SystemUIFactory.createFromConfig();

public class SystemUIFactory {... ...public static void createFromConfig(Context context) {if (mFactory != null) {return;}final String clsName = context.getString(R.string.config_systemUIFactoryComponent);if (clsName == null || clsName.length() == 0) {throw new RuntimeException("No SystemUIFactory component configured");}try {Class<?> cls = null;cls = context.getClassLoader().loadClass(clsName);mFactory = (SystemUIFactory) cls.newInstance();  //加载了一个SystemUIFactorymFactory.init(context);  //执行init()方法} catch (Throwable t) {Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);throw new RuntimeException(t);}}... ...private void init(Context context) {mRootComponent = buildSystemUIRootComponent(context);// Every other part of our codebase currently relies on Dependency, so we// really need to ensure the Dependency gets initialized early on.Dependency dependency = new Dependency();mRootComponent.createDependency().createSystemUI(dependency);dependency.start();}
}

上面这段代码,我可以看到做了一件事情,就是start了Dependency,Dependency中用来处理整个SystemUI中的依赖。

2、SystemUIFactory.getInstance().getRootComponent().inject();

这里主要是初始化SystemUIAppComponentFactory内部含@Inject的变量。

作者:pc_Li

来自:pc_Li的博客_CSDN博客-Android疑难问题,Android基础及原理领域博主

Android11 SystemUI启动流程源码分析(一)——SystemUIApplication的创建相关推荐

  1. Activity启动流程源码分析-浅析生命周期函数

    源码分析 接着上一篇 Activity启动流程源码分析-setContentView源码阅读 的讲解,本节介绍一下Activity的生命周期函数何时被调用 要看Activity的生命周期函数何时被调用 ...

  2. SpringBoot2 | SpringBoot启动流程源码分析(一)

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 SpringBoot2 | SpringBoot启动流程源码分析(一) 置顶 张书康 201 ...

  3. Activity启动流程源码分析(基于Android N)

    Activity启动流程源码分析 一个Activity启动分为两种启动方式,一种是从Launcher界面上的图标点击启动,另一种是从一个Activity中设置按钮点击启动另外一个Activity.这里 ...

  4. DataNode启动流程源码分析

    我们都知道在Hadoop hdfs文件系统中,Datanode是负责hdfs文件对应的数据块存储管理的组件,其会在启动时向NameNode汇报其上拥有的数据块,以及周期性心跳并接收来自NameNode ...

  5. SpringBoot配置外部Tomcat项目启动流程源码分析(下)

    前言 SpringBoot应用默认以Jar包方式并且使用内置Servlet容器(默认Tomcat),该种方式虽然简单但是默认不支持JSP并且优化容器比较复杂.故而我们可以使用习惯的外置Tomcat方式 ...

  6. Spark On YARN启动流程源码分析

    1.spark-submit入口介绍 一般的spark作业都是通过命令行spark-submit相关的指令来进行提交,使用--master yarn来指定提交到对应的yarn集群上,如下: ./bin ...

  7. 【源码分析】storm拓扑运行全流程源码分析

    [源码分析]storm拓扑运行全流程源码分析 @(STORM)[storm] 源码分析storm拓扑运行全流程源码分析 一拓扑提交流程 一stormpy 1storm jar 2def jar 3ex ...

  8. nimble源码学习——广播流程源码分析1

    广播流程源码分析1 在controller层有多种状态:广播.空闲.连接等等,这次分析的是广播这个状态或者叫 做角色.在前面controller层循环的分析中,可以明确controller层也有eve ...

  9. Doris FE启动流程源码详细解析

    Doris FE启动流程源码详细解析 一.简介 Apache Doris是一个现代化的MPP分析型数据库产品.仅需亚秒级响应时间即可获得查询结果,有效地支持实时数据分析.Apache Doris的分布 ...

最新文章

  1. 一行命令实现录屏,支持热键和鼠标操作,区域、帧率、格式任你选择
  2. pcb结构链表_第2章 2-1进程与PCB
  3. 海口这家只收5元的理发店火了 顾客求涨价老板都不肯
  4. IIS部署asp.net core webapi
  5. (*长期更新)软考网络工程师学习笔记——Section 10 网络安全
  6. 北斗云计算机怎么样,北斗定位2.0版服务平台来了
  7. .net core 微服务下的手工签名实现,以及消除中文乱码
  8. Jenkins分层作业和作业状态汇总
  9. MySQL日志(一条sql更新语句是如何执行的)
  10. 各省GTFP绿色全要素生产率面板数据(2004-2018年)
  11. xcode打包ipa配置手动配置证书
  12. excel服务器导出文件,excel服务器导出文件夹
  13. Leetcode-1436: 旅行终点站(6行简单解法)
  14. centos7无法上网问题
  15. windows副本未通过正版windows验证的解决!
  16. 百度APIak和sk
  17. TwinCAT3安装完成后使用过程中遇到的问题
  18. 【吴恩达机器学习笔记】1引言、单变量线性回归、线性代数回顾
  19. Abaqus硅胶管拉伸仿真
  20. 购物系统-网上书店 javaweb jsp+Servelt+JDBC连接数据库(源码分享)

热门文章

  1. 独立游戏——《爱与正义》准备开工啦!
  2. Bundler的安装和配置
  3. 放射学中基于影像组学和人工智能预测癌症预后
  4. 访问远程Redis服务。Connect to Remote Redis Server
  5. 什么是电商API接口?那如何调取呢?
  6. 微服务之服务治理相关内容
  7. 微机原理_微处理器架构
  8. Ubuntu切换中文语言
  9. eclipse默认指向WebContent目录修改为webRoot 设置说明
  10. java PDF 生成方案