目录
前言
在 Android 系统中,DVM(Dalvik 虚拟机)和 ART、应用程序进程以及运行系统的关键服务的 SystemServer 进程都是由 Zygote 进程来创建的,我们也将它称为孵化器。它通过fock的形式来创建应用程序进程和SystemServer 进程,下面我们就通过分析代码来看一下Zygote 进程是如何做这些事的。
分析步骤
1.分析ZygoteInit.java的main方法
其实ZygoteInit 的 main 方法主要做了 4 件事:
(1)创建一个 Server 端的 Socket。
(2)预加载类和资源。
(3)启动 SystemServer 进程。
(4)等待 AMS 请求创建新的应用程序进程。
2.分析registerZygoteSocket
我们可以看到主要就是创建 LocalServerSocket,也就是服务器端的 Socket,并将文件操作符作为参数传进去。在 Zygote 进程将 SystemServer 进程启动后,就会在这个服务器端的 Socket 上等待 AMS 请求 Zygote 进程来创建新的应用程序进程。
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
3.分析启动 SystemServer 进程
在forkSystemServer函数中我们可以看到,启动SystemServer的一些参数,其中就有SystemServer所在的Java类路径
再往下看,我们发现是通过forkSystemServer来创建SystemServer进程
下面我们再查看handleSystemServerProcess函数
我们看到最后的返回也是调用了一个函数,我们进入ZygoteInit.zygoteInit函数中
我们发现最后又调用了RuntimeInit.applicationInit,我们点进去
我们发现里面又调用了findStaticMain函数,通过函数的名称我们可以猜到,大概是调用main函数的方法
我们进入findStaticMain函数中发现确实是在这里获取main函数,不过最后又创建了一个MethodAndArgsCaller对象
我们查看MethodAndArgsCaller的源码发现这个类实现了Runnable接口,并且在run方法中调用了Method(也就是传进来的main函数)
然后我们再回到ZygoteInit.java文件的main函数中,我们发现forkSystemServer返回的正是Runnable的实现,而且在下面也调用了run方法(即调用了SystemServer的main函数)
然后我们再找到SystemServer.java发现里面确实有main函数,而且启动了SystemServer
4.分析runSelectLoop
runSelectLoop这个函数中的逻辑也就是等待 AMS 请求创建新的应用程序进程。下面的mServerSocket 就是我们在 registerZygoteSocket 函数中创建的服务器端Socket,调用mServerSocket.getFileDescriptor()函数用来获得该 Socket 的 fd 字段的值并添加到 fd 列表 fds 中。接下来无限循环用来等待 AMS 请求 Zygote 进程创建新的应用程序进程。
下面这段代码是通过遍历将 fds 存储的信息转移到 pollFds 数组中。然后对 pollFds 进行遍历,如果 i==0,说明服务器端 Socket 与客户端连接上了,换句话说就是,当前 Zygote进程与 AMS 建立了连接。然后通过 acceptCommandPeer 方法得到 ZygoteConnection类并添加到 Socket 连接列表 peers 中,接着将该ZygoteConnection 的 fd 添加到 fd 列表 fds中,以便可以接收到 AMS 发送过来的请求。如果 i 的值不等于 0,则说明 AMS 向 Zygote进程发送了一个创建应用进程的请求,最后调用 ZygoteConnection 的 runOnce 函数来创建一个新的应用程序进程,并在成功创建后将这个连接从 Socket 连接列表 peers 和fd 列表 fds 中清除。