SystemServer进程创建系统上下文环境(mSystemContext)
上文中,在SystemServer.java的main方法,有一步是创建系统上下问环境,在本文中详细介绍一下。
SystemServer.java createSystemContext方法
private void createSystemContext() {
// 又看到了熟悉的内容了,哈哈哈 ActivityThread
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
总结
这个方法比较简单:
- 获取ActivityThread的对象,调用的方法是ActivityThread.systemMain(),看这方法名就感觉这个对象是特意为系统而建的。
- 通过ActivityThread得到一个SystemContext
- 系统上下文环境一个主题,这个主题是啥还不清楚
- 获取系统UI上下文环境,然后设置主题
ActivityThread.java systemMain方法
@UnsupportedAppUsage //这个注释看着像是说明下面这个方法不能给应用程序使用,只能系统使用
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();
}
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
总结
这个方法也简单
- 判断一下内存的大小,低内存的关闭硬件加速,高内存的打开硬件加速
- 创建一个ActivityThread对象
- 调用attach方法
- 返回ActivityThread对象
ActivityThread.java getSystemContext方法
@UnsupportedAppUsage //只能系统调用
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
总结
这方法就是单例模式返回一个系统级别的Context
ContextImpl.java createSystemContext方法
@UnsupportedAppUsage
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null, null);
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
总结
这个方法代码简单,不多说了,具体设置的那些参数是干嘛用的,这里没有必要展开了。
ContextImpl.java setTheme方法
@Override
public void setTheme(int resId) {
synchronized (mSync) {
if (mThemeResource != resId) {
mThemeResource = resId;
initializeTheme();
}
}
}
总结
设置主题,没啥好说的
ContextImpl.java initializeTheme方法
private void initializeTheme() {
if (mTheme == null) {
mTheme = mResources.newTheme();
}
mTheme.applyStyle(mThemeResource, true);
}
总结
设置主题,没啥好说的
ActivityThread.java attach
// thread.attach(true, 0);这个是调用方式及参数
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//...
} else {
//很明显,走的是这里
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
//不要在这里设置应用程序对象-如果系统崩溃,我们将无法显示警报,我们只是想死掉。
//设置应用名称
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this); // Instrumentation
// getSystemContext().mPackageInfo 是createSystemContext方法创建的
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//context.mPackageInfo 是 LoadedApk类的对象
mInitialApplication = context.mPackageInfo.makeApplication(true, null); //Application
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
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.
//视图层级结构变更时会收到通知,这时候立即使用变更的resources
if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
null /* compat */)) {
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);
}
总结
这个方法做的事情也比较多
- 设置应用名称 system_process
- 创建 Instrumentation 对象,并初始化mThread 的值
- 创建一个Application对象(mInitialApplication),并调用onCreate方法
- 创建了一个资源变更回调,添加到ViewRootImpl的静态变量中。(功能:在视图层级结构变更时会被调用,这时候立即使用变更的resources )
上面的方法中:
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
getSystemContext().mPackageInfo 是 LoadedApk类的对象, LoadedApk类的对象在createSystemContext方法创建的:
LoadedApk.java 构造方法之一
LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.packageName = "android"; //重点
mPackageName = "android"; //重点
mAppDir = null;
mResDir = null;
mSplitAppDirs = null;
mSplitResDirs = null;
mSplitClassLoaderNames = null;
mOverlayDirs = null;
mDataDir = null;
mDataDirFile = null;
mDeviceProtectedDataDirFile = null;
mCredentialProtectedDataDirFile = null;
mLibDir = null;
mBaseClassLoader = null;
mSecurityViolation = false;
mIncludeCode = true;
mRegisterPackage = false;
mResources = Resources.getSystem();
mDefaultClassLoader = ClassLoader.getSystemClassLoader();
mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
new ApplicationInfo(mApplicationInfo));
}
总结
构造方法没啥好说的,重点看mApplicationInfo.packageName = "android"; 和 mPackageName = "android"; 后面用到了这两个变量。
继续往下:
LoadedApk.java makeApplication方法
//context.mPackageInfo.makeApplication(true, null); 调用方式及参数
@UnsupportedAppUsage
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {//显然还是mApplication == null,后面会知道
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;//从上面知道这个值是 “android”
//显然forceDefaultAppClass的值是true
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application"; //走到这里
}
try {
java.lang.ClassLoader cl = getClassLoader();
//根据前面知道 mPackageName 的值是“android”
if (!mPackageName.equals("android")) {
//不会走这里
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//最终还是用mInstrumentation来创建
// appClass = "android.app.Application";
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app; //整个LoadApk类,给mApplication赋值的就只有这里,对应了前面判断语句
if (instrumentation != null) { //传过来是null
//...
}
// Rewrite the R 'constants' for all library apks. 重写R类的constants???
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
总结
这个方法也做了挺多事情
- mApplication判空,整个LoadApk类,给mApplication赋值的就只有一处,在这里的时候mApplication还是null
- 把 appClass 的值设为"android.app.Application"
- 调用mActivityThread.mInstrumentation.newApplication创建Application,还是要用到Instrumentation,哈哈哈
- 把创建的系统Application添加到ActivityThread对象里面的mAllApplications这个列表里
- 最后是有一步重写R类的constants???这个没太看懂
Instrumentation.java newApplication方法
源码位置:frameworks\base\core\java\android\app
//从前面知道 className == "android.app.Application"
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;
}
总结
方法比较简单,不多说了
AppComponentFactory.java instantiateApplication方法
源码位置:frameworks\base\core\java\android\app
//从前面知道 className == "android.app.Application"
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
@NonNull String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Application) cl.loadClass(className).newInstance();
}
总结
方法也比较简单了,反射创建android.app.Application的对象。