安卓系统启动时首先启动init进程,而后init进程会创建zygote进程,zygote进程则会fork出来SystemServer进程。在安卓开发学习之SystemServer启动过程一文中记录了阅读SystemServer启动的过程,现在就记录一下Zygote进程的启动过程
Zygote进程的启动源自于ZygoteInit类的入口main()方法
main()方法代码如下
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
ZygoteHooks.startZygoteNoThreadCreation(); // 启动hook跟踪
try {
Os.setpgid(0, 0);
// 指定当前进程的id(第一个参数是目标进程id,第二个参数是进程组id,把第二个参数设置成第一个的值)
} catch (ErrnoException ex) {
.. // 异常
}
try {
if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
// 如果是重启sys.boot_completed值是1
MetricsLogger.histogram(null, "boot_zygote_init",
(int) SystemClock.elapsedRealtime());
} // 上报Zygote进程启动的时间,除非是进程重启
.. // 日志跟踪
RuntimeInit.enableDdms(); // 启动ddms
SamplingProfilerIntegration.start(); // 用于系统优化
boolean startSystemServer = false;
String socketName = "zygote"; // 进程套接字名字时zygote
String abiList = null; // abi列表(armeabi、armeabi-v7a、x86等)
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) { // 遍历参数列表
if ("start-system-server".equals(argv[i])) {
startSystemServer = true; // 是否启动SystemServer进程,一般都要启动
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true; // 是否启动懒式预加载
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length()); // 获取abi列表
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length()); // 获取套接字名字
} else {
.. // 异常
}
}
if (abiList == null) {
.. // 异常
}
zygoteServer.registerServerSocket(socketName); // 注册套接字
if (!enableLazyPreload) { // 如果不启动懒人式预加载
..
preload(bootTimingsTraceLog); // 就调用preload()方法进行预加载
..
} else {
Zygote.resetNicePriority(); // 启动懒人式预加载的话,就只重置fifo策略
}
SamplingProfilerIntegration.writeZygoteSnapshot(); // 保存快照
..
gcAndFinalize(); // 进行gc
..
Zygote.nativeUnmountStorageOnInit(); // 卸载root的存储空间
Seccomp.setPolicy(); // seccomp安全模式
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer); // 启动SystemServer
}
..
zygoteServer.runSelectLoop(abiList); // zygote进程进入死循环,不断准备接收新的socket连接
zygoteServer.closeServerSocket(); // 关闭zygote套接字
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run(); // 启动SystemServer时,最终会到这里调用SystemServer.main()
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
第一次启动的话,肯定不会是懒人预加载,肯定会调用preload()方法进行初始化,这个方法代码如下
static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
..
beginIcuCachePinning(); // 指令缓存
..
preloadClasses(); // 利用反射进行某些类的预加载
..
preloadResources(); // 预加载资源
..
preloadOpenGL(); // 预加载openGL
..
preloadSharedLibraries(); // 预加载native库
preloadTextResources(); // 预加载文字资源
WebViewFactory.prepareWebViewInZygote(); // 在zygote进程就预加载了webview
endIcuCachePinning(); // 结束指令缓存
warmUpJcaProviders(); // 预加载jca加密缓存
..
sPreloadComplete = true;
}
原来系统资源以及一些库的初始化都在zygote进程里就进行了,特别是webView的预加载也是这么早。
回到main()方法,然后一个比较重要的方法是startSystemServer()方法,因为这个方法会启动SystemServer进程
这个方法代码如下
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK, // IPC通信时获取锁
OsConstants.CAP_KILL, // 绕过权限检查直接向别的进程发信号
OsConstants.CAP_NET_ADMIN, // 网络管理
OsConstants.CAP_NET_BIND_SERVICE, // 绑定到1024以下的端口
OsConstants.CAP_NET_BROADCAST, // 广播
OsConstants.CAP_NET_RAW, // 使用原始套接字
OsConstants.CAP_SYS_MODULE, // 对系统内核模块进行插入删除
OsConstants.CAP_SYS_NICE, // 禁止普通用户进行线程的FIFO调度策略
OsConstants.CAP_SYS_PTRACE, // 进程跟踪
OsConstants.CAP_SYS_TIME, // 系统时间
OsConstants.CAP_SYS_TTY_CONFIG, // 配置tty(终端)信息
OsConstants.CAP_WAKE_ALARM // 系统闹钟
); // 初始化要赋予SystemServer进程的能力
if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
// 如果系统属性PROPERTY_RUNNING_IN_CONTAINER的值是false
// 就在要赋予SystemServer的能力里加上CAP_BLOCK_SUSPEND(阻止系统进程挂起)
capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
}
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
}; // 启动参数,进行权限的设置
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
// 解析启动参数,获取ZygoteConnection.Arguments对象
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
// 设置参数对象的debugFLags,判断是否JDWP调试(默认是不调试的)
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
// 根据参数里的nice-name值获取SystemProperties对应的值,并保存到参数对象的invokeWith属性里,但这个属性默认是null
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities); // fork子进程,返回子进程的pid
} catch (IllegalArgumentException ex) {
..
}
/* For child process */
if (pid == 0) { // fork完后,如果当前进程是子进程
if (hasSecondZygote(abiList)) { // 根据abiList考虑是否要进行第二次孵化
/*
这个是根据ro.product.cpu.abilist系统属性判断的,如果abiList不是这个系统属性的值,就要进行二次孵化
ro.product.cpu.abilist属性也包括了ro.product.cpu.abilist32属性,在Android-X86系统里,它们的值是
ro.product.cpu.abilist=x86,armeabi-v7a,armeabi
ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
*/
waitForSecondaryZygote(socketName); // 是的话,等待进行下一次孵化
}
zygoteServer.closeServerSocket(); // 不用的话,关闭套接字
handleSystemServerProcess(parsedArgs); // 而后继续SystemServer启动
}
return true;
}
解释都在注释里,如果fork完子进程,而且当前在子进程里,就进入下一步:handleSystemServerProcess()。这个子进程,就是SystemServer进程
由上文可知,这个方法是在SystemServer进程里被执行的,所以下面就是关于SystemServer如何被启动的内容了
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
// 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) {
Process.setArgV0(parsedArgs.niceName);
// 设置进程的参数一为启动参数里的niceName(也就是SystemServer)
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
// 获取环境变量SYSTEMSERVERCLASSPATH的值
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
// 执行SystemServer的dex优化
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
// 是否进行SystemServer性能优化
try {
File profileDir = Environment.getDataProfilesDePackageDirectory(
Process.SYSTEM_UID, "system_server");
File profile = new File(profileDir, "primary.prof");
profile.getParentFile().mkdirs();
profile.createNewFile();
String[] codePaths = systemServerClasspath.split(":");
VMRuntime.registerAppInfo(profile.getPath(), codePaths);
} catch (Exception e) {
..
}
}
}
if (parsedArgs.invokeWith != null) {
// 正常情况invokeWith为null
....
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
// 获取path的classLoader,这个classLoader用来加载SystemServer类
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
// 设置此线程的上下文classLoader
}
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
获取完SystemServer的classLoader后,调用zygoteInit()方法进行下一步初始化
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
.. // 日志
RuntimeInit.redirectLogStreams(); // 把标准输出和标准错误重定向给log.i和log.e
RuntimeInit.commonInit(); // 针对日志和异常处理进行初始化
ZygoteInit.nativeZygoteInit(); // zygote初始化
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
又是一系列的初始化操作,之后进入RuntimeInit.applicationInit()方法,此方法代码如下
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); // 设置内存最大利用率
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); // 设置sdk版本
final Arguments args;
try {
args = new Arguments(argv); // main()方法需要的参数
} catch (IllegalArgumentException ex) {
.. // 异常
}
..
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
设置内存利用率和sdk版本,并且解析完参数后,调用invoteStaticMain()方法,调用main(),此方法代码如下
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
Class> cl;
try {
cl = Class.forName(className, true, classLoader); // 反射获取SystemServer类
} catch (ClassNotFoundException ex) {
.. // 异常
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class }); // 获取main()方法
} catch (Exception ex) {
..
}
int modifiers = m.getModifiers(); // 获取main()方法的访问修饰符
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
.. // 如果不是静态公有的,就抛出异常
}
// 正常情况会抛出这个异常,这个异常在ZygoteInit.main()方法中被捕捉
throw new Zygote.MethodAndArgsCaller(m, argv);
}
正常情况下,这段代码抛出Zygote.MethodAndArgsCaller异常,并携带main()方法和方法参数,它在ZygoteInit.main()方法中捕获后(可以回去看看ZygoteInit.main()),会调用这个异常的run()方法,run()方法代码如下
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (Exception ex) {
..
}
}
执行SystemServer的main()方法,从而开始SystemServer的启动流程
关于Zygote进程的启动过程就是如此。总结一下:
进行一系列初始化(包括系统资源,openGL,webView等)后,fork一个SystemServer进程,通过抛出异常的方式开始SystemServer的主函数的执行,fork之后的zygote自己则进入等待套接字连接的死循环。
源码选自Android8.0