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桌面是如何启动的?