上一篇文章中我们已经分析了Zogote进程的启动流程SystemServer启动流程之zygote启动(一),ZygoteInit.main方法做了四件事情,其中第三件事就是启动我们的system_server,system_server进程作为zygote的嫡长子,其重要性是不言而喻的,今天我们就来分析一下其启动流程。
我们紧接着上一篇文章分析到的位置开始,上一篇文章我们分析到了ZygoteInit.main方法的第三步startSystemServer方法,此方法就是zogote用来fork新进程system_server的重要步骤。
(1)ZygoteInit.startSystemServer()
源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
//此处就是用于fork新进程system_server
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//此处调用handleSystemServerProcess方法开始system_server进程的使命
handleSystemServerProcess(parsedArgs);
}
return true;
}
Zogote将system_server进程fork出来后,将调用handleSystemServerProcess方法开始发挥system_server进程的作用了。
(2)ZygoteInit.handleSystemServerProcess()
源码:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
//关闭从zygote那里继承下来的socket
closeServerSocket();
// set umask to 0077 so new files and directories will default to owner-only permissions.
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
//设置进程名为system_server
Process.setArgV0(parsedArgs.niceName);
}
//获得SystemServer类的路径,用于后面执行SystemServer的main方法
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (parsedArgs.invokeWith != null) {
//......
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
//传入SystemServer类的加载器,执行zygoteInit方法
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
此方法主要就是加载SystemServer类,然后执行RuntimeInit.zygoteInit方法,我们进入该方法。
(3)RuntimeInit.zygoteInit()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in nativeFinishInit()
* were rationalized with Zygote startup.
*
* Current recognized args:
*
* -
[--] <start class name> <args>
*
*
* @param targetSdkVersion target SDK version
* @param argv arg strings
*/
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
//常规初始化设置
redirectLogStreams();
commonInit();
//native层初始化
nativeZygoteInit();
//调用Java层的main方法
applicationInit(targetSdkVersion, argv, classLoader);
}
对此方法我们主要就分析一下nativeZygoteInit和applicationInit两个方法,我们进入nativeZygoteInit方法。
(4)RuntimeInit.nativeZygoteInit()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static final native void nativeZygoteInit();
static AndroidRuntime* gCurRuntime = NULL;
//这里需要重点说一下,AndroidRuntime会在startReg方法中预加载大量的JNI
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
//这里将gCurRuntime变量赋值为AndroidRuntime对象
gCurRuntime = this;
}
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
这是一个native层的方法,其在native层的实现方法是AndroidRuntime.cpp文件的nativeZygoteInit方法,进入该方法可以发现,这里的gCurRuntime就是AndroidRuntime的对象,而AndroidRuntime.cpp是没有onZygoteInit方法的,所以其调用的是其子类AppRuntime的onZygoteInit方法。
//frameworks/base/cmds/app_process/app_main.cpp
namespace android {
class AppRuntime : public AndroidRuntime
{
virtual void onZygoteInit()
{
// Re-enable tracing now that we're no longer in Zygote.
atrace_set_tracing_enabled(true);
sp proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
//启动一个线程用于Binder通信
proc->startThreadPool();
}
}
}
system_server调用完nativeZygoteInit之后,便于Binder通信系统建立了联系,这样system_server就能使用Binder进行通信了。
(5)RuntimeInit.applicationInit()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
//这里直接调用invokeStaticMain方法
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
(6)RuntimeInit.invokeStaticMain()
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/**
* Invokes a static "main(argv[]) method on class "className".
* Converts various failing exceptions into RuntimeExceptions, with
* the assumption that they will then cause the VM instance to exit.
*
* @param className Fully-qualified class name
* @param argv Argument vector for main()
* @param classLoader the classLoader to load {@className} with
*/
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class> cl;
try {
//加载com.android.server.SystemServer类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
//获得main方法
m = cl.getMethod("main", new Class[] { String[].class });
} 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();
//判断main方法是否是public和static类型
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
//抛出MethodAndArgsCaller异常,将SystemServer的main方法传递过去
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
可以看到ZygoteInit.MethodAndArgsCaller是一个继承自Exception的类,invokeStaticMain最后并没有直接调用com.android.server.SystemServer的main 方法,而是抛出了一个ZygoteInit.MethodAndArgsCalle类型的异常。
那该异常是在哪里被捕获的呢?其实是在ZygoteInit的main方法中,也许之前我们都没注意。
public static void main(String argv[]) {
try{
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
}
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
}catch (MethodAndArgsCaller caller) {
//捕获到异常后调用其run方法处理
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
main函数中通过try-catch最终捕获到了MethodAndArgsCaller异常,并通过异常类的run函数来处理。
/**
* Helper exception class which holds a method and arguments and
* can call them. This is used as part of a trampoline to get rid of
* the initial process setup stack frames.
*/
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
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 });
} 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的Java世界啦,开始执行SystemServer的main方法,这里我们总结一下。
这里主要讲述了如何从ZygoteInit.startSystemServer方法执行到SystemServer.main方法。
1、首先从ZygoteInit.startSystemServer()方法调用到RuntimeInit.zygoteInit()方法,主要是做zogote的初始化操作。
2、紧接着调用RuntimeInit.applicationInit()方法,此方法通过调用invokeStaticMain()方法来加载SystemServer类,并通过抛出MethodAndArgsCaller异常的方式让ZygoteInit.main()方法捕获处理。
3、ZygoteInit.main()方法通过catch捕获该异常后,通过其run方法的 mMethod.invoke()来执行SystemServer的main方法。