Android11 SystemUI启动流程源码分析(一)——SystemUIApplication的创建
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的创建相关推荐
- Activity启动流程源码分析-浅析生命周期函数
源码分析 接着上一篇 Activity启动流程源码分析-setContentView源码阅读 的讲解,本节介绍一下Activity的生命周期函数何时被调用 要看Activity的生命周期函数何时被调用 ...
- SpringBoot2 | SpringBoot启动流程源码分析(一)
首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 SpringBoot2 | SpringBoot启动流程源码分析(一) 置顶 张书康 201 ...
- Activity启动流程源码分析(基于Android N)
Activity启动流程源码分析 一个Activity启动分为两种启动方式,一种是从Launcher界面上的图标点击启动,另一种是从一个Activity中设置按钮点击启动另外一个Activity.这里 ...
- DataNode启动流程源码分析
我们都知道在Hadoop hdfs文件系统中,Datanode是负责hdfs文件对应的数据块存储管理的组件,其会在启动时向NameNode汇报其上拥有的数据块,以及周期性心跳并接收来自NameNode ...
- SpringBoot配置外部Tomcat项目启动流程源码分析(下)
前言 SpringBoot应用默认以Jar包方式并且使用内置Servlet容器(默认Tomcat),该种方式虽然简单但是默认不支持JSP并且优化容器比较复杂.故而我们可以使用习惯的外置Tomcat方式 ...
- Spark On YARN启动流程源码分析
1.spark-submit入口介绍 一般的spark作业都是通过命令行spark-submit相关的指令来进行提交,使用--master yarn来指定提交到对应的yarn集群上,如下: ./bin ...
- 【源码分析】storm拓扑运行全流程源码分析
[源码分析]storm拓扑运行全流程源码分析 @(STORM)[storm] 源码分析storm拓扑运行全流程源码分析 一拓扑提交流程 一stormpy 1storm jar 2def jar 3ex ...
- nimble源码学习——广播流程源码分析1
广播流程源码分析1 在controller层有多种状态:广播.空闲.连接等等,这次分析的是广播这个状态或者叫 做角色.在前面controller层循环的分析中,可以明确controller层也有eve ...
- Doris FE启动流程源码详细解析
Doris FE启动流程源码详细解析 一.简介 Apache Doris是一个现代化的MPP分析型数据库产品.仅需亚秒级响应时间即可获得查询结果,有效地支持实时数据分析.Apache Doris的分布 ...
最新文章
- 一行命令实现录屏,支持热键和鼠标操作,区域、帧率、格式任你选择
- pcb结构链表_第2章 2-1进程与PCB
- 海口这家只收5元的理发店火了 顾客求涨价老板都不肯
- IIS部署asp.net core webapi
- (*长期更新)软考网络工程师学习笔记——Section 10 网络安全
- 北斗云计算机怎么样,北斗定位2.0版服务平台来了
- .net core 微服务下的手工签名实现,以及消除中文乱码
- Jenkins分层作业和作业状态汇总
- MySQL日志(一条sql更新语句是如何执行的)
- 各省GTFP绿色全要素生产率面板数据(2004-2018年)
- xcode打包ipa配置手动配置证书
- excel服务器导出文件,excel服务器导出文件夹
- Leetcode-1436: 旅行终点站(6行简单解法)
- centos7无法上网问题
- windows副本未通过正版windows验证的解决!
- 百度APIak和sk
- TwinCAT3安装完成后使用过程中遇到的问题
- 【吴恩达机器学习笔记】1引言、单变量线性回归、线性代数回顾
- Abaqus硅胶管拉伸仿真
- 购物系统-网上书店 javaweb jsp+Servelt+JDBC连接数据库(源码分享)