SystemServer进程是由Zygote进程创建的,在init.rc中指定启动的参数,SystemServer启动的服务,应用程序可以通过Context.getSystemService()来调用。
在ZygoteInit通过调用Zygote.forkSystemServer函数创建systemServer进程后,
pid = Zygote.forkSystemServer(...);如果pid等于0则表示是在子进程,则会调用handleSystemServerProcess(parsedArgs)函数处理systemServer进程。
本文以Android 13代码为例。
1,在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName); //如果parsedArgs(从Zygote传递的参数)中包含了一个nice name(友好名称),则将其设置为当前进程的argv[0](即进程名称)。
}
ClassLoader cl = getOrCreateSystemServerClassLoader(); //获取或创建SystemServer的类加载器
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl); //设置为当前线程的上下文类加载器
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl); //返回调用zygoteInit函数
}
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();//初始化运行环境
ZygoteInit.nativeZygoteInit();//启动Binder,方法在AndroidRuntime.cpp中注册
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
private static native void nativeZygoteInit();//在AndroidRuntime.cpp中,REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit)
2,在frameworks/base/core/jni/AndroidRuntime.cpp中
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit(); //gCurRuntime是app_main.cpp中AppRuntime的一个对象
}
3,在frameworks/base/cmds/app_process/app_main.cpp中
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
4,在frameworks/native/libs/binder/ProcessState.cpp中
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();//生成新线程的名称
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = sp<PoolThread>::make(isMain);
t->run(name.string());
}
}
上面的代码是在Binder框架的线程池中启动一个新的线程,用于处理Binder通信或其他相关任务。
5,在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java中
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader); //使用Class.forName(className, true, classLoader)加载指定的类。这里的true表示在加载类的同时初始化该类.
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });//通过反射拿到对应类的main方法的method对象
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { //检查找到的main方法是否同时是public和static的。如果不是,则抛出运行时异常,因为main方法必须同时满足这两个条件才能被正确调用。
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod; //Method对象表示了要调用的方法。它包含了方法的所有信息,比如方法名、参数类型、返回类型等。
/** argument array */
private final String[] mArgs; //这个字符串数组包含了调用mMethod方法时所使用的参数。由于mMethod是一个main方法,它的参数应该是一个字符串数组(String[]),所以这里直接使用String[]作为参数类型。
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//invoke 第一个参数为类对象,方法是static的话可以是null,第二个参数是一个对象数组,包含了调用方法时所使用的参数,这里只有一个元素,即mArgs字符串数组,它被包装在一个新的对象数组中,因为invoke方法要求第二个参数是Object...(可变参数)类型。
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
通过上面的代码就走到了SystemServer的main函数中。
6,在frameworks/base/services/java/com/android/server/SystemServer.java中
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
Looper.prepareMainLooper();
// Initialize the system context.
createSystemContext(); //加载系统资源
mSystemServiceManager = new SystemServiceManager(mSystemContext);
startBootstrapServices(t); //启动引导服务
startCoreServices(t); //启动核心服务
startOtherServices(t);
startApexServices(t);
Looper.loop();
}
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();//启动ATMS
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);//启动AMS
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
IPackageManager iPackageManager;
t.traceBegin("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain"); //调用了Watchdog的实例来暂停对当前线程的监控,避免在PackageManagerService启动过程中因为操作时间过长而被系统认为是无响应(ANR)
Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
mSystemContext, installer, domainVerificationService,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); //通过调用PackageManagerService.main(...)方法启动PMS
mPackageManagerService = pmsPair.first; //将Pair对象的first(即PackageManagerService的实例)保存到mPackageManagerService变量中。
iPackageManager = pmsPair.second; //将Pair对象的second(即IPackageManager的实现)保存到iPackageManager变量中,用于后续跨进程通信。
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain"); //在PMS启动完毕后,恢复对当前线程的监控。
}
}
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
t.traceBegin("StartWindowManagerService");
// WMS needs sensor service ready
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager); //启动WMS
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
t.traceEnd();
t.traceBegin("SetWindowManagerService");
mActivityManagerService.setWindowManager(wm);
t.traceEnd();
mActivityManagerService.systemReady(() -> { //launcher进程的启动从这里开始
Slog.i(TAG, "Making services ready");
t.traceBegin("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
t.traceEnd();
t.traceBegin("StartObservingNativeCrashes");
}
);
}
7,在frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java中
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
if (bootingSystemUser) {
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); //在所有可用的显示设备上启动主屏幕
t.traceEnd();
}
}
public ActivityTaskManagerInternal mAtmInternal;//ActivityTaskManagerInternal是一个抽象类public abstract class ActivityTaskManagerInternal {}
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
8,在frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java中
final class LocalService extends ActivityTaskManagerInternal {
@Override
public boolean startHomeActivity(int userId, String reason) {
synchronized (mGlobalLock) {
return mRootWindowContainer.startHomeOnDisplay(userId, reason, DEFAULT_DISPLAY);
}
}
}
9,在frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java中
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
false /* fromHomeKey */);
}
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display or default display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
final Task rootTask = getTopDisplayFocusedRootTask();
displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
}
final DisplayContent display = getDisplayContent(displayId);
// 使用reduceOnAllTaskDisplayAreas方法遍历该显示设备上的所有任务显示区域(TaskDisplayArea),并对每个区域调用startHomeOnTaskDisplayArea方法来尝试启动主屏幕。
return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey),
false /* initValue */);
}
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
// Fallback to top focused display area if the provided one is invalid.
if (taskDisplayArea == null) {
final Task rootTask = getTopDisplayFocusedRootTask();
taskDisplayArea = rootTask != null ? rootTask.getDisplayArea()
: getDefaultTaskDisplayArea();
}
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()) { // taskDisplayArea是默认的任务显示区域
homeIntent = mService.getHomeIntent(); // 获取启动主屏幕的Intent
aInfo = resolveHomeActivity(userId, homeIntent); // 通过resolveHomeActivity方法解析出对应的ActivityInfo
} else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) { // askDisplayArea需要放置次级主屏幕
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea); // 通过resolveSecondaryHomeActivity方法获取次级主屏幕的ActivityInfo和Intent
aInfo = info.first;
homeIntent = info.second;
}
if (aInfo == null || homeIntent == null) {
return false;
}
// 通过canStartHomeOnDisplayArea方法检查是否可以在当前的taskDisplayArea、给定的ActivityInfo和是否允许工具化的条件下启动主屏幕
if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
return false;
}
// Updates the home component of the intent.
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); // 设置Intent的组件为解析出的ActivityInfo对应的组件
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// Updates the extra information of the intent.
if (fromHomeKey) { // 如果fromHomeKey为true,表示该操作是由主页键触发的,会添加额外的信息到Intent中,并可能取消最近的动画
homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
if (mWindowManager.getRecentsAnimationController() != null) {
mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart();
}
}
homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason);
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
// 通过mService.getActivityStartController().startHomeActivity方法启动主屏幕活动,传入配置好的Intent、ActivityInfo、更新后的reason字符串以及taskDisplayArea。
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
return true;
}
10,在frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java中
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,TaskDisplayArea taskDisplayArea) {
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) //获取一个 ActivityStarter ,主要用于启动 Activity
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute(); //调用execute()
if (rootHomeTask.mInResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}
按照mSupervisor.scheduleResumeTopActivities继续走下去就可以启动launcher了。