上一篇博文介绍了SystemServer启动各种SystemService的过程,本章介绍Zygote孵化SystemServer进程的过程,system_server是进程名称,代码实现在 /frameworks/base/services/java/com/android/server/SystemServer.java。
目录
2. ZygoteInit.forkSystemServer()
4. ZygoteInit.handleSystemServerProcess()
5. RuntimeInit.appliactionInit()
6. RuntimeInit.findStaticMain()
一、ZygoteInit
路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,它是Zygote进程的启动类,作用是预初始化一些类,然后等待UNIX domain socket的指令。基于这些指令fork出继承VM初始状态的子进程。
二、SystemServer进程启动过程
Zygote启动system_server进程基本都在framework Java层,本文基于Android 12,整体过程如下图。
- ZygoteInit的main()中调用forkSystemServer(),组装启动systemServer进程的参数,调用Zygote.forSystemServer();
- Zygote.forSystemServer()中调用JNI方法nativeForkSystemServer(),返回pid。
- pid=0表示运行在子进程中,接着调用handleSystemServerProcess(),在该方法中调用zygoteInit()。
- zygoteInit()中先通过JNI调用nativeZygoteInit(),最后调用返回RuntimeInit.applicationInit()。
- applicationInit()中调用自己的findStaticMain(),在后者方法中通过反射获取SystemServer的Class和main(),最后返回MethodAndArgsCaller对象(它implements Runnable)。
- 最后main()方法调用forSystemServer()返回的MethodAndArgsCaller对象的run(),在其run()调用了SystemServer.main()。
三、具体函数介绍
1.ZygoteInit.main()
main()主要工作:
- 初始化DDMS(Dalvik Debug Monitor Service);
- 预加载类、库、各种资源等
- 创建server端Socket;
- 调用forSystemServer()开始fork system_server进程,调用其返回的Runnable对象的run(),即通过反射调用SystemServer.main();
- 调用zygoteServer.runSelectLoop()监听Socket。
public class ZygoteInit {
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
Runnable caller;
...
RuntimeInit.preForkInit(); //enable DDMS
...
preload(bootTimingsTraceLog); //预加载类、库、资源
...
zygoteServer = new ZygoteServer(isPrimaryZygote); //创建服务器端Socket
if (startSystemServer) {
//fork systemServer进程的入口,返回的是MethodAndArgsCaller
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
//MethodAndArgsCaller类的run()通过反射进去SystemServer.main()
r.run();
return;
}
}
// The select loop returns early in the child process after a fork and loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run();
}
}
2. ZygoteInit.forkSystemServer()
主要工作:
- 把fork system_server进程的参数String[] args转化为ZygoteArguments类;
- ZygoteArguments的部分成员变量作为参数来调用Zygote.forSystemServer(),返回fork的子进程的pid;
- pid=0,表示当前代码运行在子进程system_server中,子进程复制了Zygote进程的地址空间,包括zygote创建的socket,而该socket对system_server进程是没有作用的,因此需要调用zygoteServer.closeServerSocket()关闭。最后调用handleSystemServerProcess()。
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
String[] args = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs;
int pid;
...
ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
try {
parsedArgs = ZygoteArguments.getInstance(commandBuffer);
} catch (EOFException e) {
throw new AssertionError("Unexpected argument error for forking system server", e);
}
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
if (pid == 0) {
//pid=0,表示当前代码运行在子进程system_server中
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//system_server进程负责了zygote进程的地址空间,但是它不需要该socket,所以要关闭
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
3. Zygote.forkSystemServer()
该方法主要调用nativeForkSystemServer(),该方法通过JNI调用/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中该方法。
4. ZygoteInit.handleSystemServerProcess()
/**
* Finish remaining work for the newly forked system server process.
*/
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
...
ClassLoader cl = getOrCreateSystemServerClassLoader();
...
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mDisabledCompatChanges, parsedArgs.mRemainingArgs, cl);
}
上述获取ClassLoader c1最终调用该方法,使用boot class loader来加载SystemServer类。
static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
String libraryPath = System.getProperty("java.library.path");
// We use the boot class loader, that's what the runtime expects at AOT.
ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
}
4. ZygoteInit.zygoteInit()
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
RuntimeInit.redirectLogStreams(); //重定向log输出
RuntimeInit.commonInit(); //初始化Runitme
ZygoteInit.nativeZygoteInit(); //JNI方法,启动Binder线程池
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader);
}
5. RuntimeInit.appliactionInit()
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
//初始化VM环境
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
final Arguments args = new Arguments(argv);
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
6. RuntimeInit.findStaticMain()
该方法就是利用classLoader加载SystemServer类,然后获取其main(),最后返回MethodAndArgsCaller对象。
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
cl = Class.forName(className, true, classLoader);
Method m;
m = cl.getMethod("main", new Class[] { String[].class });
...
return new MethodAndArgsCaller(m, argv);
}
7. MethodAndArgsCaller.run()
static class MethodAndArgsCaller implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
...
}
}
}