- 作者:老汪软件技巧
- 发表时间:2024-12-27 21:05
- 浏览量:
SystemServer进程主要用于创建系统服务,我们比较熟知的AMS、PMS和WMS都是由它创建的。
环境参数:
在线源码网址:xrefandroid
Zygote处理SystemServer进程
Zygote进程的主要任务之一就是启动SystemServer进程,那SystemServer是如何被启动的呢?先看Zygote进程的main函数:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
...
Runnable caller;
try {
...
zygoteServer = new ZygoteServer(isPrimaryZygote);
//默认为ture,用于启动SystemServer
if (startSystemServer) {
//fork出SystemServer进程并启动
//在子进程中返回Runnable对象用于在SystemServer进程中去启动执行
//在父进程中返回null
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
//表示当前代码逻辑在子进程SystemServer中
r.run();
return;
}
}
...
}
...
}
在Zygote进程的main()函数中,通过forkSystemServer()方法去创建SystemServer进程,并在子进程中返回了一个Runnable对象。直接走进forkSystemServer()方法:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#forkSystemServer
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
....
/* 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,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
"--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;
try {
...
/* Request to fork the system server process */
//fork出SystemServer进程
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
//1
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//关闭zygote进程创建的Socket
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
在forkSystemServer()方法中,定义了参数数组args,其中com.android.server.SystemServer非常重要;后面通过Zygote.forkSystemServer()方法fork出SystemServer进程,根据fork机制,返回来的pid为0则表示当前逻辑位于fork出来的进程。
注释1处的代码只会在SystemServer进程中运行,首先会根据判断,去启动32位的Secondary Zygote。其次因为SystemServer进程复制了Zygote进程的地址空间,所以会得到Zygote进程创建的Socket,但是这个Socket对于SystemServer进程没有用处,因此在System进程中调用closeServerSocket()方法去关闭该Socket。随后通过handleSystemServerProcess()方法去处理SystemServer进程后续的事务。
如何fork出SystemServer进程
根据前文,Zygote进程通过Zygote.forkSystemServer()方法fork出SystemServer进程,具体如下:
@frameworks/base/core/java/com/android/internal/os/Zygote.java#forkSystemServer
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
核心点在于方法nativeForkSystemServer(),找到其对应的Native方法,位于frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
@frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
jlong effective_capabilities) {
...
//1
pid_t pid = zygote::ForkCommon(env, true,
fds_to_close,
fds_to_ignore,
true);
if (pid == 0) {
// System server prcoess does not need data isolation so no need to
// know pkg_data_info_list.
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
false, nullptr, nullptr, /* is_top_app= */ false,
/* pkg_data_info_list */ nullptr,
/* allowlisted_data_info_list */ nullptr, false, false);
}
...
return pid;
}
进入ForkCommon()函数
@frameworks/base/core/jni/com_android_internal_os_Zygote.cpp#ForkCommon
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore,
bool is_priority_fork,
bool purge) {
...
//fork
pid_t pid = fork();
...
return pid;
}
最终看到是通过fork()函数创建子进程,自此SystemServer进程就创建成功了。
总结:Zygote进程在Java层通过JNI定义接口调用到Native层fork()方法,创建了SystemServer进程。
上文提到通过Zygote.forkSystemServer()方法fork出SystemServer进程后,会通过handleSystemServerProcess()方法去处理SystemServer进程的后续事务:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#handleSystemServerProcess
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
...
if (parsedArgs.mInvokeWith != null) {
...
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
...
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
继续走到ZygoteInit的静态方法zygoteInit()中去:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#zygoteInit
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
RuntimeInit.commonInit();
//1.启动Binder线程池
ZygoteInit.nativeZygoteInit();
//返回Runnable,被调用run方法后进入SystemServer的main方法
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
private static native void nativeZygoteInit();
注释1调用Native方法nativeZygoteInit(),用来启动Binder线程池。注释2用于进入SystemServer的main()方法。
启动Binder线程池
nativeZygoteInit()是一个Native方法,我们需要找到它对应的JNI文件,根据JNI的命名规则,其对应的C++方法为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类型的指针,指向其子类AppRunTime,它在app_main.cpp中定义:
@frameworks/base/cmds/app_process/app_main.cpp#onZygoteInit
virtual void onZygoteInit()
{
sp proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
startThreadPool()方法用于启动一个Binder线程池,SystemServer进程可以通过使用Binder与其他进程进行通信。
SystemServer进程首先会去启动一个Binder线程池的,主要是方便与其他进程进程通信。
进入SystemServer的main方法
回到ZygoteInit.java#zygoteInit()方法,启动Binder线程池后,会调用RuntimeInit的applicationInit()方法,向上返回一个Runnable对象:
@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#applicationInit
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
...
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
继续进入到findStaticMain()方法
@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#findStaticMain
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class> cl;
try {
//1.反射获取对象
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();
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.
*/
return new MethodAndArgsCaller(m, argv);
}
参数className为前面提到com.android.server.SystemServer,通过反射创建SystemServer对象,然后找到main函数,随后封装为一个Runnable类型的MethodAndArgsCaller对象返回,最终会返回到ZygoteInit.java的main函数中:
@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main
public static void main(String[] argv) {
...
try {
...
//默认为ture,用于启动SystemServer
if (startSystemServer) {
//fork出SystemServer进程并启动
//在子进程中返回Runnable对象用于在SystemServer进程中去启动执行
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
//表示当前代码逻辑在子进程SystemServer中
r.run();
return;
}
}
...
}
...
}
调用MethodAndArgsCaller的run()方法
static class MethodAndArgsCaller 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 {
//调用传进来的方法,也就是前面的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);
}
}
}
当run()方法被调用,SystemServer进程就会走到SystemServer.java的main()方法中去。
注意:最后将SystemServer.java的main()函数调用逻辑封装成Runnable类型的MethodAndArgsCaller对象,该对象作为ZygoteInit.java中forkSytemServer()函数的返回值,在ZygoteInit.java的main()函数中调用其run()函数去启动,主要是为了让SystemServer的main()方法看起来像是SystemServer进程的入口函数。
因此SystemServer进程由Zygote进程调用本地方法fork而出,随后SystemServer首先去开启了Binder线程池,便于与其他进程通信,然后再通过反射创建SystemSever对象,随后进入SystemServe的main()方法。
解析SystemServer进程
下面来看SystemSever的main()方法:
@frameworks/base/services/java/com/android/server/SystemServer.java#main
public static void main(String[] args) {
new SystemServer().run();
}
直接new了一个对象后进入到run方法:
private void run() {
try {
...
//创建消息Looper
Looper.prepareMainLooper();
...
//加载动态库android_serves.so
// Initialize native services.
System.loadLibrary("android_servers");
//初始化系统上下文
// Initialize the system context.
createSystemContext();
...
//创建SystemServiceManager
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
}
// Start services.
try {
t.traceBegin("StartServices");
//启动引导服务
startBootstrapServices(t);
//启动核心服务
startCoreServices(t);
//启动其他服务
startOtherServices(t);
//启动Apex相关服务
startApexServices(t);
}
...
//进入loop()循环等待和处理请求
// Loop forever.
Looper.loop();
}
总结
SystemServer进程相关内容可以大致分为3步:
Zygote进程fork出SystemServer进程SystemServer进程做一些准备工作,比如启动Binder线程池,然后再去找到执行下一步的入口,SystemServer的main函数进入SystemServer的main函数: