参考1
参考2
概念
(1)在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的;
(2)当ActivityManagerService启动一个应用程序的时候,就会通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的进程;
(3)系统中的两个重要服务PackageManagerService和ActivityManagerService,都是由SystemServer进程来负责启动的,而SystemServer进程本身是Zygote进程在启动的过程中fork出来的。
Zygoteinit.java
(1)设置DDMS可用,初始化启动参数。
(2)调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯。
(3)调用startSystemServer函数来启动SystemServer组件
(4)调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。
ZygoteInit.registerZygoteSocket
(1)这个socket接口是通过文件描述符来创建的,
(2)这个文件描符代表的就是我们前面说的/dev/socket/zygote文件了。
(3)这个文件描述符是通过环境变量ANDROID_SOCKET_ENV得到的
(4)ZygoteInit.registerZygoteSocket函数可以直接使用这个文件描述符来创建一个Java层的LocalServerSocket对象。如果其它进程也需要打开这个/dev/socket/zygote文件来和Zygote进程进行通信,那就必须要通过文件名来连接这个LocalServerSocket了
public class ZygoteInit {
......
/**
* 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) {
......
}
try {
sServerSocket = new LocalServerSocket(
createFileDescriptor(fileDesc));
} catch (IOException ex) {
.......
}
}
}
......
}
Zygoteinit.startSytemServer()
(1)Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件
(2)pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
public class ZygoteInit {
......
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
......
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
......
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
......
}
Zygote.handleSystemServerProcess
(1)Zygote进程创建的子进程会继承Zygote进程在前面创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket函数来关闭它。
(2)接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作
public class ZygoteInit {
......
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}
......
}
RuntimeInit.zygoteInit()
(1)一个是调用zygoteInitNative函数来执行一个Binder进程间通信机制的初始化工作
(2)调用上面传进来的com.android.server.SystemServer类的main函数。
public class RuntimeInit {
......
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
......
zygoteInitNative();
......
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
......
}
ZygoteInit.runSelectLoopMode
(1)等待ActivityManagerService来连接这个Socket。
(2)然后调用ZygoteConnection.runOnce函数来创建新的应用程序
public class ZygoteInit {
......
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList fds = new ArrayList();
ArrayList peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
......
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);
}
}
}
}
......
}
总结:Zygote启动流程
初始化DDMS
注册Zygote进程的Socket
加载class、resource、OpenGL、WebView等各种资源
fork出SystemServer进程
启动SystemServer进程
调用runSelectLoop()一直监听Socket信息
收到创建应用程序Socket消息,调用ZygoteConnection#runOnce()。在runOnce()中调用Zygote#forkAndSpecialize()创建应用进程
启动应用进程
系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。
Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。
当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。