先熟悉下:http://blog.csdn.net/jianguo_liao19840726/article/details/15810633
public static void main(String argv[]) {
registerZygoteSocket();
preloadClasses();
preloadResources();
if (argv[1].equals("true")) {
startSystemServer();
}
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
}
上面被我删除了一些代码,主要有关方法说明:
1、registerZygoteSocket();注册zygote的socket、即提供socket的服务端
2、preloadClasses(); preloadResources(); 预加载类和资源
3、startSystemServer(); 启动system_server进程
4、运行的孵化器进程的socket的I/O多路复用select循环,等待接受新连接
5、closeServerSocket();关闭socket
先看注册socket,此方法在其注释中已经很好的进行了解释
/**
* Registers a server socket for zygote command connections
*
* @throws RuntimeException when open fails
*/
private static void registerZygoteSocket() {
if (sServerSocket == null) {
int fileDesc;
try {
String env = System.getenv(ANDROID_SOCKET_ENV);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(
ANDROID_SOCKET_ENV + " unset or invalid", ex);
}
try {
sServerSocket = new LocalServerSocket(
createFileDescriptor(fileDesc));
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
有关预加类
private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime();
InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(
PRELOADED_CLASSES);
//PRELOADED_CLASSES常量值为:preloaded-classes在framework/base下面
BufferedReader br
= new BufferedReader(new InputStreamReader(is), 256);
int count = 0;
String line;
while ((line = br.readLine()) != null) {
// Skip comments and blank lines.
line = line.trim();
if (line.startsWith("#") || line.equals("")) {
continue;
}
try {
//通过反射来加载类
Class.forName(line);
}
}
}
加载资源是加载framework-res.apk中的资源,即我们常用的com.android.R.XXX资源,系统默认资源
startSystemServer();先不讲,放到下一个帖子来讲
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
/*
* Call gc() before we block in select().
* It's work that has to be done anyway, and it's better
* to avoid making every child do it. It will also
* madvise() any free memory as a side-effect.
*
* Don't call it every time, because walking the entire
* heap is a lot of overhead to free a few hundred bytes.
*/
if (loopCount <= 0) {
gc();
loopCount = GC_LOOP_COUNT;
} else {
loopCount--;
}
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
其中最重要的一句selectReadable见上面,我们点进去这个方法
static native int selectReadable(FileDescriptor[] fds) throws IOException;
从上面来看是个native方法,我们就不深究了,但是从注释来看,我们也能大致了解到这个方法的意思了,下面是两个方法的注释
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
/**
* Invokes select() on the provider array of file descriptors (selecting
* for readability only). Array elements of null are ignored.
*
从上面的注释来看就是一个socket的读写I/O的多路复用,即接收来自socket的客户短的并发的请求,因为是在while中,所以我们来看看,select返回值的相应的处理
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
从上面来看,先是链接上,然后ZygoteConnection.runOnce()来处理客户端的请求