Android系统中,所有的应用程序以及SystemServer都是由Zygote进程孕育(fork)出来的。接上文,上文介绍从Native世界进入了Java世界。而且java世界的大门就是ZygtoeInit.java。这次我们看ZygtoeInit中处理了哪些功能。
Android P
正文
涉及文件
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java frameworks\base\core\java\com\android\internal\os\ZygoteServer.java frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java frameworks\base\core\java\com\android\internal\os\RuntimeInit.java frameworks\base\core\jni\com_android_internal_os_Zygote.cpp frameworks\base\core\jni\com_android_internal_os_ZygoteInit.cpp

接上一篇《Zygote的启动之一app_main》,启动了com.android.internal.os.ZygoteInit进入了Java的世界,
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
args中的参数
{"start-system-server", "--abi-list=arm64-v8a", "--socket-name=zygote", "--enable-lazy-preload"}
进入ZygoteInit.java世界,启动的依旧是main()函数。
public static void main(String argv[]) { //[1]创建ZygoteServer ZygoteServer zygoteServer = new ZygoteServer(); final Runnable caller; try { for (int i = 1; i < argv.length; i++) { //是否有start-system-server参数,有就需要启动startSystemServer if ("start-system-server".equals(argv[i])) { //是否启动SystemServer startSystemServer = true; } else if ("--enable-lazy-preload".equals(argv[i])) { //是否延迟加载 enableLazyPreload = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { //32位 --abi-list=armeabi-v7a,armeabi //64位 --abi-list=arm64-v8a abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { //设置socket名 socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } //[2]注册socket zygoteServer.registerServerSocketFromEnv(socketName); //懒惰预加载,enableLazyPreload=true; if (!enableLazyPreload) { //这里暂时不走 preload(bootTimingsTraceLog); } else { Zygote.resetNicePriority(); } //[3]提前加载Resources preloadResources(); //提前加载文本Resources preloadTextResources(); //主动GC gcAndFinalize(); //我这64位时startSystemServer= true if (startSystemServer) { //[4]创建SystemServer Runnable r = forkSystemServer(abiList, socketName, zygoteServer); if (r != null) { r.run(); return; } } //[5]循环中。对于zygote不会退出,至于fork的子进程,是会退出的 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { throw ex; } finally { //关闭socket zygoteServer.closeServerSocket(); } if (caller != null) { caller.run(); } }
上面主要是如下功能:
创建ZygoteServer
注册socket
预加载资源
创建SystemServer
runSelectLoop()一直循环处理
下面就简单的走一下流程。
创建ZygoteServer
ZygoteServer zygoteServer = new ZygoteServer();
功能很简单,就是创建ZygoteServer对象,后面需要。
注册socket
zygoteServer.registerServerSocketFromEnv(socketName);
也就是处理功能都是ZygoteServer类。
socketName就是之前init.zygote64_32.rc中配置的。
64位socketName:zygote 32位socketName:zygote_secondary
就是注册了对应的socket,后面用于通信
void registerServerSocketFromEnv(String socketName) { if (mServerSocket == null) { //略 FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); //创建mServerSocket mServerSocket = new LocalServerSocket(fd); mCloseSocketFd = true; } }
预加载资源
//enableLazyPreload= true
if (!enableLazyPreload) {
//暂时不走这里,后面会加载
preload(bootTimingsTraceLog);
} else {
Zygote.resetNicePriority();
}
//提前加载Resources
preloadResources();
//提前加载文本Resources
preloadTextResources();
提前加载系统相关的资源,这也是为啥开发中推荐优先用系统资源文件。
预加载的资源是存在framework-res.apk中。
forkSystemServer()
if (startSystemServer) {
// fork SystemServer,并返回一个 Runnable
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
这里是创建出SystemServer进程,然后后面找到main()入口函数,进行启动SystemServer.java
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer){
//略
//配置uid,gid,group等参数
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", //启动类
};
int pid;
try {
//参数转换
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
//默认为false
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
//fork一个进程,就是创建SystemServer
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//子进程
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//关闭子进程的socket
zygoteServer.closeServerSocket();
//处理SYstemServer进程
return handleSystemServerProcess(parsedArgs);
}
return null;
}
进入handleSystemServerProcess
handleSystemServerProcess()
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
if (parsedArgs.niceName != null) {
//设置进程名为system_server
Process.setArgV0(parsedArgs.niceName);
}
//加载SystemServer类的路径
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
//systemServerClasspath不为空
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
//profileSystemServer = false
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
//略
}
//parsedArgs.invokeWith = null
if (parsedArgs.invokeWith != null) {
//不走这
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建ClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
//进入ZygoteInit.zygoteInit()
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
systemServerClasspath存储的内容
/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar:/system/framework/car-frameworks-service.jar
zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){
//略
//native方法
ZygoteInit.nativeZygoteInit();
//进入applicationInit,返回Runnable
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
applicationInit()
此时进入了RuntimeInit.java中,我们看applicationInit()
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {
//略
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
findStaticMain()
看名字就是找到类的启动入口。
根据前面,知道className传入的是com.android.server.SystemServer
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {
Class<?> cl;
try {
//加载com.android.server.SystemServer类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
}
Method m;
try {
//查找main函数
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
}
int modifiers = m.getModifiers();
//判断是否有static和public修饰
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
//MethodAndArgsCaller就是一个Runnable
return new MethodAndArgsCaller(m, argv);
}
最终就创建的一个Runnable。
MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//Method = com.android.server.SystemServer的main函数
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
//略
}
}
}
上面我们知道,fork出SystemServer之后,进行了null判断,然后启动了run()
这里用了反射
# Method = com.android.server.SystemServer的main函数
mMethod.invoke(null, new Object[] { mArgs });
到这里就算启动了com.android.server.SystemServer,并进入了main()。
疑惑
if (startSystemServer) {
// fork SystemServer,并返回一个 Runnable
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
//这里进入了MethodAndArgsCaller的run()
r.run();
//哈哈这里return
return;
}
}
上面fork出SystemServer后,r不为null,也就是执行了下面代码
if (r != null) {
r.run();
return;
}
这里竟然直接return了,那后面代码不执行?
其实不是,这个就需要看Linux中的fork的原理。上面return的只是子进程(SystemServer进程)程序,而父类进程还是会继续往下执行。也就是进入了runSelectLoop()
runSelectLoop()
//循环中。 caller = zygoteServer.runSelectLoop(abiList);
对于父进程,也就是Zygote的会进入循环中;对于子进程SystemServer在上面会return,其他子进程,会返回caller,然后退出。
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//mServerSocket是之前创建的socket
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
//死循环
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
for (int i = pollFds.length - 1; i >= 0; --i) {
//采用I/O多路复用机制,当客户端发出连接请求或者数据处理请求时,则执行continue
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
//有socket客户端连接上,创建一个新的ZygoteConnection
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
//添加socket的描述符
fds.add(newPeer.getFileDesciptor());
} else {
try {
//客户端发送了请求
ZygoteConnection connection = peers.get(i);
//这里创建了一个Runnable,是不是子进程,这里会设置
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
//如果在子进程,就返回Runnable
return command;
} else {
//判断是否需要关闭socket
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
}
}
}
}
}
runSelectLoop()是个死循环,也就是Zygote是一直存在并处理对应事物的。主要做了如下事
添加之前创建的socket并获取请求消息
进入死循环读取请求消息
i == 0时,有新客户端,创建新的ZygoteConnection
i != 0时,处理客户端发送的请求,如果是子进程,就返回Runnable
processOneCommand()
下面就介绍一下,当收到新的子进程创建流程。
Runnable processOneCommand(ZygoteServer zygoteServer) {
try {
//从socket读取命令
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
//如果没有读取到命令,socket可能断了,
if (args == null) {
isEof = true;
return null;
}
//创建Arguments对象,这里会解析args中的命令
parsedArgs = new Arguments(args);
//根据参数值进行处理
if (parsedArgs.abiListQuery) {
handleAbiListQuery();
return null;
}
//handlePreload也就是之前没有预加载的
if (parsedArgs.preloadDefault) {
handlePreload();
return null;
}
//略
// fork进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
if (pid == 0) {//如果是子线程,进入这里
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//handleChildProc
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else { //如果是父进程,走这里
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
这里主要如下工作
readArgumentList()从socket读取命令
Arguments解析读取的命令并执行对应的功能
根据parsedArgs的信息进行fork进程
处理子进程并返回Runnable
readArgumentList()
主要是从socket中读取命令
private String[] readArgumentList()throws IOException {
int argc;
try {
//socket读取一行命名
String s = mSocketReader.readLine();
if (s == null) {
return null;
}
argc = Integer.parseInt(s);
} catch (NumberFormatException ex) {
Log.e(TAG, "invalid Zygote wire format: non-int at argc");
throw new IOException("invalid wire format");
}
if (argc > MAX_ZYGOTE_ARGC) {
throw new IOException("max arg count exceeded");
}
String[] result = new String[argc];
for (int i = 0; i < argc; i++) {
//读取出所有的命令
result[i] = mSocketReader.readLine();
if (result[i] == null) {
throw new IOException("truncated request");
}
}
return result;
}
Arguments
//创建Arguments对象,这里会解析args中的命令 parsedArgs = new Arguments(args);
Arguments(String args[]) throws IllegalArgumentException {
parseArgs(args);
}
最终是调用parseArgs()解析命令,很长,略过,就是对命令解析并对parsedArgs的属性进行赋值。
handlePreload()
根据之前parsedArgs中解析的命令,执行对应的功能。我这里以handlePreload()为例。
if (parsedArgs.preloadDefault) {
handlePreload();
//返回null,也就是处理完后就不会继续执行后面的代码
return null;
}
private void handlePreload() {=
try {
//判断是否有预加载过,如果有就调过,没有就执行preload()
if (isPreloadComplete()) {
mSocketOutStream.writeInt(1);
} else {
preload();
mSocketOutStream.writeInt(0);
}
} catch (IOException ioe) {
throw new IllegalStateException("Error writing to command socket", ioe);
}
}
isPreloadComplete()返回true的前提是有执行过preload()中调用的ZygoteInit.preload(),后面会看到。
preload()
protected void preload() {
ZygoteInit.lazyPreload();
}
哈哈 进入ZygoteInit.java
ZygoteInit.lazyPreload()
public static void lazyPreload() {
Preconditions.checkState(!sPreloadComplete);
preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
}
ZygoteInit.preload()
static void preload(TimingsTraceLog bootTimingsTraceLog) {
//只做了一件事,preloadClasses
preloadClasses();
//sPreloadComplete这里赋值为true
sPreloadComplete = true;
}
preloadClasses()看函数名就名,预加载类,就是提前加载一些类而已。
forkAndSpecialize()
这根据中parsedArgs的信息,然后fork一个新的进程。我们关注pid,不关心怎么fork。
如果pid=0,表示子进程,走处理子进程流程,返回Runnable
如果pid!=0,表示父进程,走处理父进程的流程,返回null
handleChildProc()
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
//关闭socket通信
closeSocket();
//设置进程名
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
//一般这里为invokeWith = null
//除非parsedArgs解析socket命令行中有对应的命令,略过,看下面
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
//isZygote = false,就是parsedArgs.startChildZygote
if (!isZygote) {
//走这里。又回到了ZygoteInit类
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
ZygoteInit.zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
//RuntimeInit初始化相关
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
//native方法
ZygoteInit.nativeZygoteInit();
//执行applicationInit
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
zygoteInit()也是不干活的,真正处理进入RuntimeInit
RuntimeInit.applicationInit()
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//找到static的main入口
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
也是不干活的,哈哈,这个跟上面启动com.android.server.SystemServer是找到static的mian入口一样的流程了?
最后都一样,findStaticMain()返回Runnable,然后启动run(),通过反射直接进入main()入口,也就是算启动了进程。
到这里,就基本走完了一圈,zygote也一直循环,等待着新的命令进行fork出新的进程。
参考文章
《》
《深入理解Android卷1(邓凡平)》
《》
《》
