「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
SystemServer.createSystemContext函数流程分析
SystemServer在启动过程中,在其run函数中,会调用createSystemContext函数来初始化系统上下文Context,从这个函数来看,其中部分代码较为复杂,因此,今天我们单独来看下这个函数具体做了什么动作
createSystemContext();
private void createSystemContext() {
// 初始化ActivityThread对象
ActivityThread activityThread = ActivityThread.systemMain();
// 获取系统上下文Context
mSystemContext = activityThread.getSystemContext();
// 设置系统默认主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
// 设置系统SystemUI默认主题
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
初始化ActivityThread对象
ActivityThread.systemMain
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
// 低内存的设备不允许使用硬件加速来绘制界面,因为硬件加速功能对于进程有很多额外的开销
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
// 直接new一个ActivityThread,然后调用其attach函数
// 注意attach函数的两个参数分别为true和0
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
初始化一个ActivityThread对象,并且调用其attach函数
ActivityThread() {
// 单例模式创建ResourcesManager对象
mResourcesManager = ResourcesManager.getInstance();
}
// 接下来调用其attach函数
private void attach(boolean system, long startSeq) {
// 设置ActivityThread.sCurrentActivityThread为当前ActivityThread对象
sCurrentActivityThread = this;
// 设置ActivityThread.mSystemThread = true
mSystemThread = system;
if (!system) {
// ...... 第一个参数为true,这边分支无法进入,省略
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
// 设置DDMS进程名称
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
// 初始化一个Instrumentation对象,并调用其basicInit函数
mInstrumentation = new Instrumentation();
// 将当前的ActivityThread对象设置给Instrumentation的mThread参数
mInstrumentation.basicInit(this);
// 创建一个ContextImpl对象
// 传递system ContextImpl对象的LoadedApk对象
// getSystemContext()函数中会创建和返回一个单例的ContextImpl对象,这个对象的mPackageInfo对象为初始化的一个LoadedApk对象
// ContextImpl.createAppContext函数初始化一个ContextImpl对象
// 这块的代码其实个人有点不太理解,因为getSystemContext函数应用单例模式,返回一个ContextImpl作为system context,然后返回其LoadedApk对象
// 而ContextImpl.createAppContext函数初始化ContextImpl对象后,直接使用其mPackageInfo参数,
// 根据代码分析,此处返回的依旧是上述初始化的LoadedApk对象,那么此处为何需要多此一举呢?直接使用system context的LoadedApk对象不就好了么?
ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
// 初始Application,下属两条语句的主要工作是:
// 初始化了一个Application对象,然后调用其attach函数,最后调用其onCreate函数,
// 同时设定LoadedApk.mApplication为当前的Application对象,
// 并且将 Application对象添加到mActivityThread.mAllApplications中
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
// 4. 配置ViewRootImpl的配置变化回调函数类
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
// ...... 无效代码,省略
// We need to apply this change to the resources immediately, because upon returning
// the view hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
null /* compat */,
mInitialApplication.getResources().getDisplayAdjustments())) {
updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
mResourcesManager.getConfiguration().getLocales());
// This actually changed the resources! Tell everyone about it.
if (mPendingConfiguration == null
|| mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
mPendingConfiguration = globalConfig;
sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
}
}
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
如上的代码注释中已经将这个函数的主要功能均已经描述,此处不再重复赘述
获取系统上下文Context
// 获取系统上下文Context
// 在此前的的ActivityThread.systemMain函数中,
// ActivityThread.attach函数其实已经调用过此处的ContextImpl.createSystemContext函数,
// 而该函数又是单例的,因此此处会直接返回ActivityThread.mSystemContext对象
mSystemContext = activityThread.getSystemContext();
// 设置系统默认主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
// 设置系统SystemUI默认主题
// 同system context一样,此处的ActivityThread.getSystemUiContext函数,也是使用了单例模式
// 初始化一个参数名为mSystemUiContext的ContextImpl对象
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
总结
在SystemServer.createSystemContext函数中,主要是做了如下的几个操作
-
调用ActivityThread.systemMain函数,
在这个函数中初始化一个ActivityThread对象,
并且设置ActivityThread.sCurrentActivityThread为当前ActivityThread对象,
且设置ActivityThread.mSystemThread = true,同时调用Activity.attach函数
同时设置初始化ActivityThread.mInstrumentation
初始化ActivityThread.mInitialApplication为Application对象,并调用其attach函数和onCreate函数,同时设置LoadedApk.mApplication为该Application对象,并将这个Application对象添加到mActivityThread.mAllApplications中
-
通过ActivityThread的getSystemContext和getSystemUiContext函数,初始化两个ContextImpl对象,分别标识System和SystemUi的上下文,并且设置他们的默认主题
附
SystemServer.createSystemContext函数调用时序图