Android Zygote进程启动过程

Zygote是由init进程启动的。
而在Android系统中,Dalvik/ART虚拟机、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程(孵化器)来创建的。

Zygote进程的启动过程

init进程启动Zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start放来启动Zygote进程的。
来看frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
     
	//...
	while (i < argc) {
     
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
     
            zygote = true; //如果当前运行在Zygote进程中,则设为true
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
     
        	//如果当前运行在SystemServer进程中,则将startSystemServer设置为true
            startSystemServer = true;
        } 
        //...
    }
    //...
    //如果运行在Zygote进程中
	if (zygote) {
     
		//启动ZygoteInit
	    runtime.start("com.android.internal.os.ZygoteInit", args, zygote); //启动Zygote进程
	} 
	//...
}

Zygote进程都是通过fork自身来创建子进程的,这样Zygote进程以及它的子进程都可以进入app_main.cpp的main函数,所以main函数中会判断运行在哪个进程。

接着,来看frameworks/base/core/jni/AndroidRuntime.cpp#start()
这部分详见我的博客Android虚拟机的启动 源码分析

AndroidRuntime#start()函数会启动Java虚拟机,接着通过JNI调用ZygoteInit的main方法后,Zygote便进入了Java框架层,此前是没有任何代码进入Java框架层的,换句话说Zygote开创了Java框架层。

来看frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
     
 	//...
 	//创建一个Server端的Socket,socketName的值为"zygote"
    zygoteServer.registerServerSocket(socketName);
	//...
	//预加载资源
    preload(bootTimingsTraceLog);
    //...
    if (startSystemServer) {
     
    	//启动SystemServer进程
        Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    }
	//等待AMS请求
	zygoteServer.closeServerSocket();
}

可以看到ZygoteInit的main方法主要做了4件事情

  1. 创建一个Server端的Socket
  2. 预加载类和资源
  3. 启动SystemServer进程
  4. 等待AMS请求创建新的应用程序进程

来看下registerServerSocket,这里创建了一个Server端的Socket,
然后,当启动SystemServer进程后,会执行ZygoteServer的runSelectLoop方法,无限轮询来等待ActivityManagerService请求Zygote来创建新的应用程序进程。

Runnable runSelectLoop(String abiList) {
     
    //...
    fds.add(mServerSocket.getFileDescriptor()); //将创建的服务器端Socket的fd字段添加到fds中
	//...
	//无限循环等待AMS的请求
    while (true) {
     
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
      //通过遍历将fds存储的信息转移到pollFds数组中
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
     
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
     
            throw new RuntimeException("poll failed", ex);
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
      //对pollFds进行遍历
            if ((pollFds[i].revents & POLLIN) == 0) {
     
                continue;
            }

            if (i == 0) {
      //如果i==0,说明服务器端Socket与客户端Socket连接上了 (Zygote进程与AMS建立了连接)
            	//通过acceptCommandPeer方法得到ZygoteConnection类
                ZygoteConnection newPeer = acceptCommandPeer(abiList); 
                //添加到Socket连接列表peers中
                peers.add(newPeer);
                //将该ZygoteConnect的fd添加到fds中,以便可以接受到AMS发送过来的请求
                fds.add(newPeer.getFileDesciptor());
            } else {
      //如果i!=0,说明AMS像Zygote进程发送了一个创建应用进程的请求 
            	//调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程
                boolean done = peers.get(i).runOnce(this); 
                if(done){
     
                	//将这个连接从Socket连接列表peers和fds中移除
                	peers.remove(i);
                	fds.remvoe(i);
                }
            }
        }
    }
}

Zygote的IPC没有采用binder,而是采用了Socket,binder机制是应用程序启动之后,自己创建的

Zygote进程启动小结

Zygote进程启动做了如下几件事:

  1. 创建AppRuntime并调用其start方法,启动Zygote进程
  2. 创建Java虚拟机并为Java虚拟机注册JNI方法
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java层
  4. 通过registerServerSocket()创建服务器端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序。
  5. 启动SystemServer进程

你可能感兴趣的:(Android,Framework,Android,Zygote,进程,启动,过程)