前言
在系统启动流程(三)之解析zygote启动过程,我们知道了Zygote进程负责启动Systemserver进程的。在这篇文章中,我们具体讲讲Zygote启动SystemServer进程时,经历了什么?
SystemServer主要是用来创建各种系统服务的,像AMS、PMS、WMS等常见的系统服务,都是在SystemServer进程里创建的,它们并没有属于自己的一个进程。
时序图
还是先来看看时序图吧:
源码流程
1、main()
在ZygoteInit.java文件里,main()方法里调用了startSystemServer()方法,就是来启动SystemServer进程的,源码如下:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
*****省略部分代码*****
if (startSystemServer) {
//注意,在这里启动了SystemServer进程
startSystemServer(abiList, socketName, zygoteServer);
}
//一直循环,等待AMS的请求,去fork子进程
zygoteServer.runSelectLoop(abiList);
}
2、startSystemServer()
再来看看startSystemServer()方法里面做了什么:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
*****省略部分代码*****
//当前运行在SystemServer进程中
if (pid == 0) {
//关闭Zygote进程创建的Socket,因为用不到
zygoteServer.closeServerSocket();
handleSystemServerProcess(parsedArgs);
}
return true;
}
SystemServer进程复制了Zygote进程的地址空间,所以也会得到Zygote进程创建的Socket,但SystemServer用不到,所以调用了zygoteServer.closeServerSocket()关闭了Socket。
3、handleSystemServerProcess()
我们接着来看看handleSystemServerProcess(parsedArgs);的源码:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
*****省略部分代码*****
if (parsedArgs.invokeWith != null) {
*****省略部分代码*****
}else{
if (systemServerClasspath != null) {
//创建一个PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
首先通过createPathClassLoader()创建了一个PathClassLoader,接着继续调用zygoteInit()。
4、zygoteInit()
我们继续看源码:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
*****省略部分代码*****
//启动Binder线程池
ZygoteInit.nativeZygoteInit();
//进入SystemServer的main()方法
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
首先调用nativeZygoteInit()方法,一看方法的名字就知道调用了Native层的代码,是用来启动Binder线程池的(Binder通信用的),启动完Binder线程池后,再调用RuntimeInit.applicationInit()方法,就进入SystemServer的main方法。
这里我们先来研究下,如何启动Binder线程池的。
4-1 启动Binder线程池
nativeZygoteInit是一个Native方法,所以我们得去找它对应的JNI文件,如下:
//代码文件位置:frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
}
通过JNI的数组JNINativeMethod methods\[] ,可以知道nativeZygoteInit方法对应的JNI文件是AndroidRuntime.cpp的com\_android\_internal\_os\_ZygoteInit\_nativeZygoteInit函数:
//代码文件位置:frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
这里的gCurRuntime是AndroidRuntime类型的指针,具体指向的是AndroidRuntime的子类AppRuntime,它在app\_main.cpp里定义。所以我们接着来看AppRuntime的onZygoteInit方法:
//代码文件位置:frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
}
可以看到 proc->startThreadPool();就是用来启动一个Binder线程池的,这样SystemServer进程就可以使用Binder来与其他进程进行通信了。
4-2 进入SystemServer的main方法
前面我们知道了在ZygoteInit.java里的zygoteInit()方法中,先是调用ZygoteInit.nativeZygoteInit();来开启Binder线程池,接着调用RuntimeInit.applicationInit(),进入SystemServer的main方法:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
*****省略部分代码*****
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
在applicationInit()方法中,主要调用了invokeStaticMain()方法:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
try {
//通过反射得到SystemServer类
cl = Class.forName(className, true, classLoader);
}
try {
//接着,找到SystemServer的main()方法
m = cl.getMethod("main", new Class[] { String[].class });
}
//最后把main方法跟着异常抛出去
throw new Zygote.MethodAndArgsCaller(m, argv);
}
这里面的className,就是外部一路传进来的"com.android.server.SystemServer"。
先是通过反射拿到cl也就是SystemServer类,接着找到SystemServer的main方法,再接着把main方法传入MethodAndArgsCaller异常中并抛出这个异常,在外部的ZygoteInit.java的main方法中,会捕获这个异常,捕获后会调用SystemServer.main方法:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
*****省略部分代码*****
//捕获到MethodAndArgsCaller异常
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
}
}
当捕获到Zygote.MethodAndArgsCaller 时,会去调用caller.run(),这个caller还是Zygote.MethodAndArgsCaller 类型:
//代码文件位置:frameworks/base/core/java/com/android/internal/os/Zygote.java
public static class MethodAndArgsCaller extends Exception
implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//在这里,调用了SystemServer的main方法
mMethod.invoke(null, new Object[] { mArgs });
}
}
}
到此,就进入了SystemServer的main方法了。
系列文章
点击直达→→ 更多系统启动流程文章
有所收获的朋友,请多多关注、点赞,谢谢大家!