throw ex;
}
String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
Log.i(“Zygote”, "Process: zygote socket opened, supported ABIS: " + abiListString);
return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
Arrays.asList(abiListString.split(“,”)));
}
}
建立Socket连接的流程很明朗了,如下所示:
- 创建LocalSocket对象。
- 将LocalSocket与LocalServerSocket建立连接,建立连接的过程就是LocalSocket对象在/dev/socket目录下查找一个名称为"zygote"的文件,然后将自己与其绑定起来,这样就建立了连接。
- 创建LocalSocket的输入流,以便可以接收Zygote进程发送过来的数据。
- 创建LocalSocket的输出流,以便可以向Zygote进程发送数据。
1.2 ZygoteInit.main(String argv[])
ZygoteInit是Zygote进程的启动类,该类会预加载一些类,然后便开启一个循环,等待通过Socket发过来的创建新进程的命令,fork出新的 子进程。
ZygoteInit的入口函数就是main()方法,如下所示:
public class ZygoteInit {
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
try {
//…
registerZygoteSocket(socketName);
//…
//开启循环
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, “Zygote died with exception”, ex);
closeServerSocket();
throw ex;
}
}
// 开启一个选择循环,接收通过Socket发过来的命令,创建新线程
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList fds = new ArrayList();
ArrayList peers = new ArrayList();
//sServerSocket指的是Socket通信的服务端,在fds中的索引为0
fds.add(sServerSocket.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;
}
try {
//处理轮询状态,当pollFds有时间到来时则往下执行,否则阻塞在这里。
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException(“poll failed”, ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
//采用IO多路复用机制,当接收到客户端发出的连接请求时或者数据处理请求到来时则
//往下执行,否则进入continue跳出本次循环。
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
//索引为0,即为sServerSocket,表示接收到客户端发来的连接请求。
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
}
//索引不为0,表示通过Socket接收来自对端的数据,并执行相应的操作。
else {
boolean done = peers.get(i).runOnce();
//处理完成后移除相应的文件描述符。
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
}
可以发现ZygoteInit在其入口函数main()方法里调用runSelectLoop()开启了循环,接收Socket发来的请求。请求分为两种:
- 连接请求
- 数据请求
没有连接请求时Zygote进程会进入休眠状态,当有连接请求到来时,Zygote进程会被唤醒,调用acceptCommadPeer()方法创建Socket通道ZygoteConnection
private static ZygoteConnection