同样是 fork 自 zygote 进程,系统服务进程与应用进程有什么区别呢?先说回 zygote 进程做的事情,在 ZygoteInit 类中调用 main 方法,
public static void main(String argv[]) {
//省略...
final Runnable caller;
//省略...
//1.注册 socket
zygoteServer.registerServerSocketFromEnv(socketName);
//2.启动系统服务进程
if(startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if(r != null) {
r.run();
return;
}
}
//3.监听启动进程请求
caller = zygoteServer.runSelectLoop(abiList);
//在子进程中执行
if (caller != null) {
caller.run();
}
}
main 方法里主要做了 3 件事情,1.注册 socket 端口,2.启动系统服务进程,3.监听 fork 进程请求。注册 socket 先不管,监听 fork 进程请求,之前也整理过了,阅读笔记见 Android 进阶解密读书笔记2 。整理完 Android 进阶解密读书笔记2 之后,发现系统服务进程的启动和应用程序进程的启动有很多相似点,所以在此对比整理。
根据上面代码,先来看看 forkSystemServer 方法,
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
//省略...
//这里设置一些参数,留意最后一个参数值,这个就等同于启动应用进程的入口点 ActivityThread
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",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
//省略...
//这步是 fork 系统服务进程,创建应用进程用的是 Zygote.forkAndSpecialize 方法
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
//省略...
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//这步说是系统服务进程不需要 socket,于是就把 zygote 进程 fork 来的 socket 关闭
zygoteServer.closeServerSocket();
//继续处理启动系统服务进程
return handleSystemServerProcess(parsedArgs);
}
//省略...
}
再进一步看看 handleSystemServerProcess 方法,
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs){
//省略...
//这步就和创建应用进程时调的方法是一样了,包括后面的创建 Binder 线程池,反射调用 main 方法。
return ZygoteInit.zygoteInit(parseArgs.targetSdkVersion, parseArgs.remainingArgs, cl);
}
最后,系统服务进程启动后会调用 com.android.server.SystemServer 的 main 方法,这个类就是前面设置参数时指定的。
总结
通过上述分析对比,启动系统服务进程和启动应用程序进程的相同点:
- 在 zygote 进程上,起点都在 main 方法中。
- 都需要做一些参数设置准备。
- 最后都调用了 ZygoteInit 的 zygoteInit 静态方法。在方法内部都去创建了 Binder 线程池,调用入口类的 main 方法。
启动系统服务进程和启动应用程序进程的不同点:
- 系统服务进程在 zygote 进程启动时就会启动,应用进程则需要看情况,zygote 进程监听处理。
- 系统服务进程创建时调用了 Zygote.forkSystemServer 方法,应用进程创建时则调用 Zygote.forkAndSpecialize 这个通用方法。
- 系统服务进程的入口类是 SystemServer,应用进程的入口类是 ActivityThread。以及他们各自 *main *方法的工作内容也是不同的。