该系列文章总纲链接:专题总纲目录 Android Framework 总纲
本章关键点总结 & 说明:
这里因为整体的导图太大,因此截取一部分 ,方便大家看的清楚:
zygote分裂 这一部分实际上使用的就是前面zygote和SystemServer启动的步骤,在上图中用蓝色部分进行简单表示
同时,下面的图是开机启动流程分析 持续迭代的效果,可放大观看。
说明:思维导图是基于之前文章不断迭代的,本章内容我们关注➕"启动SystemServer ->SS"部分即可
Zygote的分裂解读
Zygote分裂出system_server后,就通过runSelectLoopMode等待并处理来自AMS的消息
这里以一个Activity的启动为例,具体分析Zygote是如何分裂和繁殖的。
1 AMS发送请求
AMS是由SS创建的。通过startActivit来启动一个新的Activity,最后调用到AMS中的startProcessLocked函数,代码如下所示:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
if (app.pid > 0 && app.pid != MY_PID) {
checkTime(startTime, "startProcess: removing from pids map");
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
checkTime(startTime, "startProcess: done removing from pids map");
app.setPid(0);
}
...
/**
当AMS需要启动一个新进程时,会通过socket将ActivityThread类名等重要信息的参数传递给zygote
Process.start
{下面的entryPoint的值是"android.app.ActivityThread"}
->startViaZygote
-->argsForZygote.add("--runtime-init");//参数初始化,这个参数很重要
-->{add("--setuid=" + uid);add("--setgid=" + gid);一些其他参数处理}
-->return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote)
--->openZygoteSocketIfNeeded
---->ZygoteState.connect(ZYGOTE_SOCKET);{创建并连接到zygote}
---->ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);{创建并连接到secondary_zygote}
--->zygoteSendArgsAndGetResult
---->将args通过socket写入到zygote/secondary_zygote中
---->从zygote/secondary_zygote中读取数据{int{数据大小+数据}+boolean}
*/
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
...//异常处理
}
最后的调用zygoteSendArgsAndGetResult,使得AMS向Zygote发送请求。
注意:由于AMS驻留于SystemServer进程中,所以正是SS向Zygote发送了消息。
2 Zygote响应请求
回到ZygoteInit中,处理代码在 runSelectLoop()中,代码如下:
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
FileDescriptor[] fdArray = new FileDescriptor[4];
//sServerSocket是我们先前在registerZygoteSocket建立的Socket
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
...
fdArray = fds.toArray(fdArray);
//selectReadable内部调用select,使用多路复用I/O模型。当有客户端连接或有数据时,则selectReadable就会返回。
index = selectReadable(fdArray);//返回-1:错误,返回0:fd不在监听的集合fd_set内,返回>0:fd在fd_set中
if (index == 0) {
//如有监听到一个客户端连接上,其客户端在Zygote的代表是ZygoteConnection
//acceptCommandPeer->return ZygoteConnection(sServerSocket.accept(), abiList);
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer); //添加peer对象
fds.add(newPeer.getFileDescriptor());//将newPeer的fd添加fds的描述符集合中
} else {
boolean done;
//客户端发送了请求,peers.get返回的是ZygoteConnection
//后续处理将交给ZygoteConnection的runOnce函数完成。
done = peers.get(index).runOnce(); //后面根据AMS发来的数据来创建对象时会调用该方法
if (done) {//处理完请求从fd_set中移除fd
peers.remove(index);
fds.remove(index);
}
}
}
}
当有请求数据发来时,Zygote都会调用ZygoteConnection的runOnce函数。runOnce的实现如下所示:
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
...
/**
readArgumentList
->mSocketReader.readLine();读取参数个数字符串转换为argc
->循环读取参数,总大小为argc,读完放到mSocketReader中
*/
args = readArgumentList();//读取AMS即SS发送过来的参数
descriptors = mSocket.getAncillaryFileDescriptors();//获取可操作客户端文件描述符
...//异常处理
...
checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize");
//Zygote根据AMS传递的参数创建一个子进程。
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,parsedArgs.appDataDir);
checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");
...
try {
if (pid == 0) {
//子进程处理,这个子进程是我们要创建的ActivityThread进程
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
/**
handleChildProc
->closeSocket();
->ZygoteInit.closeServerSocket();
->RuntimeInit.zygoteInit
-->nativeZygoteInit();//最终会调用AppRuntime的onZygoteInit,在那个函数中建立了和Binder的关系
-->applicationInit(targetSdkVersion, argv, classLoader);
--->invokeStaticMain方法{抛出MethodAndArgsCaller异常,携带类名为ActivityThread}
---->mMethod.invoke(null, new Object[] { mArgs });//启动对应的ActivityThread进程
*/
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
//zygote进程接下来的处理
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
/**
handleParentProc,父进程的收尾工作
->获取当前子进程的pid,通过pid和pipeFd来确认usingWrapper
->mSocketOutStream.writeInt(pid);
->mSocketOutStream.writeBoolean(usingWrapper);
*/
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
说明:所有app的父进程都是zygote
3 Zygote分裂总结
- Zygote的分裂由SS控制,SS创建AMS,之后AMS请求创建新的应用进程。
- AMS通过socket通讯模型与zygote进行通讯,发送对应应用程序的相关信息。
- Zygote接收到AMS发来的相关应用程序信息,创建对应的APP进程。