System Server 分析
16lz
2021-12-04
SystemServer 是 Android Java 层的系统服务模块,这个模块主要功能就是管理供 Android 应用开发的 system service.
一.SystemServer 类是如何启动的
让我们从 Android 的启动过程看起,查看 init.rc 文件,就会发现下面这一行service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server
我们知道 zygote 进程是整个 Android 的孵化器进程,所有的 Activity 进程均是通过它来生成的。我们发现在 zygote 进程启动过程中指定了这么一个参数“– start-system-server” ,这个参数就是在 zygote 进程启动的同时启动 SystemServer 。
那么 SystemServer 是以什么样的形式启动的呢?是单独的一个进程还是线程,分析一下 zygote 进程的启动过程就明白了。在 Android 中 zygote 进程启动其实就是启动 /system/bin/app_process 这个进程,这个进程的源代码在 frameworks/base/cmds/app_process/app_main.cpp 中。
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
由于 zygote 进程启动过程有“ –zygote” 这个参数,所以走的是下面这步
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
查看对象 runtime 的类型的定义,
class AppRuntime : public AndroidRuntime
因此查看 AndroidRuntime 的 start 方法中的一段代码 (frameworks/base/core/jni/AndroidRuntime.cpp)
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
其中 startClass 即为 “com.android.internal.os.ZygoteInit” ,这段代码调用了 com.android.internal.os.ZygoteInit 的 main 函数。
那么再往下看 ZygoteInit 类的 main 函数,其中的一段 MethodAndArgsCaller 代码为
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
调用了 startSystemServer () ,这个函数启动了一个子进程来作为 SystemServer 的载体,
1. 它首先指定 SystemServer 进程的参数 ;
2. 根据指定的参数来创建 SystemServer 进程;
3. 调用 handleSystemServerProcess 启动第一步指定进程参数过程中指定的类,此时为“ com.android.server.SystemServer ” ,启动的这个进程在 ps 查看后显示为” system_server ” 。
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[];
String ashmem_size = System.getProperty("gralloc.ashmem_size");
if ((null != ashmem_size) && (0 != ashmem_size.length())) {
args = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--capabilities=130104352,130104352",
"--rlimit=8,",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
args[4] = args[4].concat(ashmem_size);
args[4] = args[4].concat(",");
args[4] = args[4].concat(ashmem_size);
} else {
args = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--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);
/*
* Enable debugging of the system process if *either* the command line flags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if ("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
int[][] rlimits = new int[0][0];
if (parsedArgs.rlimits != null) {
rlimits = parsedArgs.rlimits.toArray(rlimits);
}
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, rlimits,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
通过以上过程就会调用到 SystemServer 类,且是运行在一个名为“ system_server” 的进程中,这个进程为 zygote 的子进程。
虽然 SystemServer 类是运行在 system_server 中的,但是它并不运行在 system_server 的主线程中。
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in finishInit()
* were rationalized with Zygote startup.<p>
*
*/
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// TODO: Doing this here works, but it seems kind of arbitrary. Find
// a better place. The goal is to set it up for applications, but not
// tools like am.
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
commonInit();
zygoteInitNative();
int curArg = 0;
for ( /* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
Process.setArgV0(niceName);
}
}
if (curArg == argv.length) {
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
/**
* 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()
*/
private static void invokeStaticMain(String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// 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);
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);
}
/*
* 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.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
由代码可以看出,在调用函数 invokeStaticMain 的最后会抛出一个异常。
public static class MethodAndArgsCaller extends Exception implements Runnable
回过头再看一下 ZygoteInit 类的 main 函数中的一段代码
catch (MethodAndArgsCaller caller) {
caller.run();
}
其实就是在这个抛出的异常中启动了 SystemServer 类,且这个异常为一个 Runnable 类型,因此 SystemServer 类就运行在 system_server 进程中的一个新的线程里。
二.SystemServer 执行内容
1. 执行 frameworks/base/cmds/system_server/library/system_init.cpp 中的 system_init 函数,启动当前进程,也就是进程 system_server 的 pool thread ,以便执行 Binder IPC 操作。
2. 向 SM(Service Manager) 添加系统服务。
一.SystemServer 类是如何启动的
让我们从 Android 的启动过程看起,查看 init.rc 文件,就会发现下面这一行service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server
我们知道 zygote 进程是整个 Android 的孵化器进程,所有的 Activity 进程均是通过它来生成的。我们发现在 zygote 进程启动过程中指定了这么一个参数“– start-system-server” ,这个参数就是在 zygote 进程启动的同时启动 SystemServer 。
那么 SystemServer 是以什么样的形式启动的呢?是单独的一个进程还是线程,分析一下 zygote 进程的启动过程就明白了。在 Android 中 zygote 进程启动其实就是启动 /system/bin/app_process 这个进程,这个进程的源代码在 frameworks/base/cmds/app_process/app_main.cpp 中。
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
由于 zygote 进程启动过程有“ –zygote” 这个参数,所以走的是下面这步
runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
查看对象 runtime 的类型的定义,
class AppRuntime : public AndroidRuntime
因此查看 AndroidRuntime 的 start 方法中的一段代码 (frameworks/base/core/jni/AndroidRuntime.cpp)
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
其中 startClass 即为 “com.android.internal.os.ZygoteInit” ,这段代码调用了 com.android.internal.os.ZygoteInit 的 main 函数。
那么再往下看 ZygoteInit 类的 main 函数,其中的一段 MethodAndArgsCaller 代码为
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
调用了 startSystemServer () ,这个函数启动了一个子进程来作为 SystemServer 的载体,
1. 它首先指定 SystemServer 进程的参数 ;
2. 根据指定的参数来创建 SystemServer 进程;
3. 调用 handleSystemServerProcess 启动第一步指定进程参数过程中指定的类,此时为“ com.android.server.SystemServer ” ,启动的这个进程在 ps 查看后显示为” system_server ” 。
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[];
String ashmem_size = System.getProperty("gralloc.ashmem_size");
if ((null != ashmem_size) && (0 != ashmem_size.length())) {
args = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--capabilities=130104352,130104352",
"--rlimit=8,",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
args[4] = args[4].concat(ashmem_size);
args[4] = args[4].concat(",");
args[4] = args[4].concat(ashmem_size);
} else {
args = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--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);
/*
* Enable debugging of the system process if *either* the command line flags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if ("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
int[][] rlimits = new int[0][0];
if (parsedArgs.rlimits != null) {
rlimits = parsedArgs.rlimits.toArray(rlimits);
}
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, rlimits,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
通过以上过程就会调用到 SystemServer 类,且是运行在一个名为“ system_server” 的进程中,这个进程为 zygote 的子进程。
虽然 SystemServer 类是运行在 system_server 中的,但是它并不运行在 system_server 的主线程中。
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in finishInit()
* were rationalized with Zygote startup.<p>
*
*/
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// TODO: Doing this here works, but it seems kind of arbitrary. Find
// a better place. The goal is to set it up for applications, but not
// tools like am.
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
commonInit();
zygoteInitNative();
int curArg = 0;
for ( /* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
Process.setArgV0(niceName);
}
}
if (curArg == argv.length) {
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
/**
* 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()
*/
private static void invokeStaticMain(String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// 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);
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);
}
/*
* 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.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
由代码可以看出,在调用函数 invokeStaticMain 的最后会抛出一个异常。
public static class MethodAndArgsCaller extends Exception implements Runnable
回过头再看一下 ZygoteInit 类的 main 函数中的一段代码
catch (MethodAndArgsCaller caller) {
caller.run();
}
其实就是在这个抛出的异常中启动了 SystemServer 类,且这个异常为一个 Runnable 类型,因此 SystemServer 类就运行在 system_server 进程中的一个新的线程里。
二.SystemServer 执行内容
1. 执行 frameworks/base/cmds/system_server/library/system_init.cpp 中的 system_init 函数,启动当前进程,也就是进程 system_server 的 pool thread ,以便执行 Binder IPC 操作。
2. 向 SM(Service Manager) 添加系统服务。
更多相关文章
- Android(安卓)init 启动过程分析
- Android(安卓)UI学习 - Tab的学习和使用
- Android(安卓)init 启动过程分析
- 安装android sdk 遇到几个问题
- Activity 与 ActivityManagerService 的启动过程
- Android---33---四种加载模式
- 关于程序中Activity若干问题知识点总结
- Android运行机制
- Android(安卓)UI学习 - Tab的学习和使用