4.3.5 执行runSelectLoopMode方法
回到ZygoteInit.java的main方法,分析zygote的最后一步工作:执行runSelectLoopMode方法,代码如下:
private static void runSelectLoopMode()throws MethodAndArgsCaller{
ArrayList<FileDescriptor>fds=new ArrayList();
ArrayList<ZygoteConnection>peers=new ArrayList();
FileDescriptor[]fdArray=new FileDescriptor[4];
/sServerSocket是registerZygoteSocket中建立的Socket/
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount=GC_LOOP_COUNT;
while(true){
int index;
if(loopCount<=0){
gc();
loopCount=GC_LOOP_COUNT;
}else{
loopCount—;
}
try{
fdArray=fds.toArray(fdArray);
/*selectReadable是一个Native方法,其JNI实现方法位于
*com_android_internal_os_ZygoteInit.cpp中,名为
*com_android_internal_os_ZygoteInit_selectReadable,
*方法内部调用了select系统函数等待客户端连接,内容如下:
*do{
*err=select(nfds,&fdset, NULL, NULL, NULL);
*}while(err<0&&errno==EINTR);
*/
index=selectReadable(fdArray);
}catch(IOException ex){
throw new RuntimeException("Error in select()",ex);
}
/*当客户端有连接时,selectReadable方法返回,返回值便是传给
selectReadable的参数fdArray中某个fd的索引/
if(index<0){
throw new RuntimeException("Error in select()");
}else if(index==0){//有连接
/*acceptCommandPeer内部通过
*new ZygoteConnection(sServerSocket.accept()
调用系统函数accept接受连接请求,并将这个连接加入peers中/
ZygoteConnection newPeer=acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
}else{//有请求
boolean done;
/peers.get(index)返回ZygoteConnection,将请求交给runOnce方法处理/
done=peers.get(index).runOnce();
if(done){
peers.remove(index);
fds.remove(index);
}
}
}
}
zygote在startSystemServer成功后,便进入一个无限循环,通过Socket监听客户端的连接请求。如果有请求到来,便调用runOnce方法处理请求。这个Socket便是在registerZygoteSocket中注册的服务Socket。既然zygote在system_server成功创建后,开始监听Socket请求,这个客户端又是什么呢?客户端会发送什么样的请求呢?在回答这两个问题之前,先解决一个问题:Android的Home桌面是如何启动的?