在上一篇博文中我们进行了有关Zygote进程的分析,我们知道Zygote进程创建了一个重要的进程–system_server进程后就进入了无限循环中,之后Android系统中的重要任务就交给了system_server进程,作为zygote的嫡长子进程,system_server进程的意义非凡,今天我们来分析一下system_server进程。
创建system_server进程
在ZygoteInit中main方法中,通过调用startSystemServer方法开启了system_server进程。该方法主要为创建system_server进程准备了一些参数,并调用本地方法forkSystemServer创建system_server进程。让我们来看一下startSystemServer方法的代码:
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
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=130104352,130104352",
"--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);
/* 创建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);
}
/* 子进程中执行 */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
这里的代码并不复杂,可以看到,他调用了forkSystemServer方法来创建一个新的进程,之后在子进程,即system_server进程中执行handleSystemServerProcess方法。下面我们来看一下forkSystemServer方法,它是一个native方法对应的源文件在dalvik\vm\native\dalvik_system_Zygote.cpp中。代码如下:
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
pid = forkAndSpecializeCommon(args, true);
/* zygote进程检查其子进程是否死掉 */
if (pid > 0) {
int status;
ALOGI("System server process %d has been created", pid);
gDvm.systemServerPid = pid;
/* 如果system_server进程退出,则zygote进程也会被杀掉 */
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
}
RETURN_INT(pid);
}
从代码中可以看到在forkAndSpecializeCommon方法中,我们创建了子进程,并返回了子进程id,接下来我检查如果system_server进程是否退出,若是的话则zygote进程也将会被被干掉,由此可见其重要性。接下来我们来看forkAndSpecializeCommon的代码,这个system_server进程的创建真的是千峰百转啊。。。
static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{
pid_t pid;
uid_t uid = (uid_t) args[0];
gid_t gid = (gid_t) args[1];
ArrayObject* gids = (ArrayObject *)args[2];
u4 debugFlags = args[3];
ArrayObject *rlimits = (ArrayObject *)args[4];
u4 mountMode = MOUNT_EXTERNAL_NONE;
int64_t permittedCapabilities, effectiveCapabilities;
char *seInfo = NULL;
char *niceName = NULL;
//传入参数isSystemServer为true
if (isSystemServer) {
permittedCapabilities = args[5] | (int64_t) args[6] << 32;
effectiveCapabilities = args[7] | (int64_t) args[8] << 32;
} else {
......
}
if (!gDvm.zygote) {
dvmThrowIllegalStateException(
"VM instance not started with -Xzygote");
return -1;
}
// 在第一次调用fork函数之前需要调用
if (!dvmGcPreZygoteFork()) {
ALOGE("pre-fork heap failed");
dvmAbort();
}
setSignalHandler();
//向log文件中写入一些数据
dvmDumpLoaderStats("zygote");
//子进程被fork出来
pid = fork();
if (pid == 0) {
//在这里根据传入的参数对子进程做出一些处理,例如设置进程名,设置各种id等
......
}
return pid;
}
至此system_server进程终于被创建出来,我们可以看到system_server进程也是通过Linux系统特有的Fork机制分裂克隆出来的。在fork之前,我们还有一个重要方法没有分析–setSignalHandler方法,该方法用来设置信号处理,下面让我来看一下吧。
static void setSignalHandler()
{
int err;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sigchldHandler;
err = sigaction (SIGCHLD, &sa, NULL);//设置信号处理函数,该信号是子进程死亡的信号
if (err < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
}
static void sigchldHandler(int s)
{
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/* 打印出我们所关心的进程的死亡状态. */
......
/*
* 如果刚刚销毁的进程是system_server, 同时杀死zygote进程
* 这样system_server进程和zygote进程将会被init进程重启
*/
if (pid == gDvm.systemServerPid) {
ALOG(LOG_INFO, ZYGOTE_LOG_TAG,
"Exit zygote because system server (%d) has terminated",
(int) pid);
kill(getpid(), SIGKILL);
}
}
if (pid < 0) {
ALOG(LOG_WARN, ZYGOTE_LOG_TAG,
"Zygote SIGCHLD error in waitpid: %s",strerror(errno));
}
}
这里我们发现我们之前已经看到在forkSystemServer方法中已经检查过system_server进程是否死亡,为什么这里还要再一次进行检查?这是为了防止在我们还没有得到fork子进程的pid时,system_server进程就已经死亡的情况。
总结一下:system_server进程的创建经历了漫长的历程:首先startSystemServer中调用了native方法forkSystemServer;之后在native方法forkSystemServer中调用了forkAndSpecializeCommon方法;在forkAndSpecializeCommon方法中fork之前还调用了setSignalHandler来设置信号处理项。这样,我们的system_server进程终于被创建起来,同时他还和zygote进程保持着同生共死的关系。
system_server进程的职责
在startSystemServer的方法中我们可以看到,在创建进程之后,在子进程即system_server进程中会执行handleSystemServerProcess方法,这便是system_server的职责所在,下面我们来看一下:
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
// 设置权限.
Libcore.os.umask(S_IRWXG | S_IRWXO);
......
if (parsedArgs.invokeWith != null) {
......
} else {
/* 剩余的参数传递到SystemServer. */
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}
}
可以看到最后system_server进程来到了RuntimeInit中,它的实现在frameworks\base\core\java\com\android\internal\os\RuntimeInit.java中
public static final void zygoteInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
//关闭System.out和System.err,使用Android log
redirectLogStreams();
//做一些常规初始化
commonInit();
//native层初始化,调用此方法之后system_server将与Binder通信系统建立联系,这样就可以使用Binder了
nativeZygoteInit();
applicationInit(targetSdkVersion, argv);
}
private static void applicationInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
......
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
invokeStaticMain(args.startClass, args.startArgs);
}
可以看到,最终我们调用了invokeStaticMain方法,该方法的传入参数在startSystemServer方法中被设置,其传入参数的类名是”com.android.server.SystemServer”
private static void invokeStaticMain(String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
cl = Class.forName(className);
} 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 });
} 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))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/* 抛出的异常在ZygoteInit.main()中被截获 */
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
让我们来看看被截获的语句:
catch (MethodAndArgsCaller caller) {
caller.run();//调用了caller的run方法
}
run方法代码:
public void run() {
try {
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);
}
}
可以看到,在函数最后抛出异常,在ZygoteInit.main()中被截获,由于传递的参数类名是”com.android.server.SystemServer”,这样我们调用了MethodAndArgsCaller.run()方法去执行了SystemServer类的静态main方法。(关于ZygoteInit可以参考上一篇博文:Android源码分析–Zygote进程分析)
public static void main(String[] args) {
......
// Mmmmmm... more memory!
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
// system server一直在运行, 所以他需要尽可能有效的利用内存
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
Environment.setUserRequired(true);
System.loadLibrary("android_servers");
Slog.i(TAG, "Entered the Android system server!");
// native方法,进行一些传感器服务的初始化
nativeInit();
// 创建一个单独的线程,在这里启动系统的各项服务
ServerThread thr = new ServerThread();
thr.initAndLoop();
}
最终,system_server开启了一个新的线程,并执行了它的initAndLoop方法,其也被定义在SystemServer.java中,该方法的代码较多,其主要的工作就是开启了系统中的各项服务,如电池服务,蓝牙服务等等。并调用了Looper的prepareMainLooper方法进行消息循环,然后处理消息,这里不再赘述。
最后,我们来总结一下:
- 首先system_server执行handleSystemServerProcess方法来完成自己的使命;
- 之后调用RuntimeInit.zygoteInit方法,在这里我们进行了一些常规的初始化工作已经native层的初始化,从而与Binder通信建立联系;
- 之后调用invokeStaticMain方法,利用抛出异常的方法在ZygoteInit的main方法中截获并去执行SystemServer的main方法;
- 在SystemServer的main方法中,我调用nativeInit方法去初始化一些传感器服务,并开启了单独的线程去开启Android系统中的各项服务,并调用了Looper的prepareMainLooper方法进行消息循环,然后处理消息