一、Zygote简介
init会创建Zygote进程,SystemServer进程和应用进程都是Zygote(孵化器)fock(复制进程)出来的。所以有必要了解下Zygote的流程。
二、Zygote启动流程
分析Zygote启动首先会调用ZygoteInit的main函数。
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
......
try {
......
//创建Server Socket
zygoteServer.registerServerSocketFromEnv(socketName);
......
if (startSystemServer) {
//创建启动SystemServer进程
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
......
}
......
//等待AMS socket连接,请求fork新进程
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
......
}
ZygoteInit的main函数主要功能:
- 1.创建Server Socket
- 2.创建和启动SystemServer进程
- 3.等待AMS连接socke和发送创建新进程的请求
2.1创建Server Socket
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
void registerServerSocketFromEnv(String socketName) {
if (mServerSocket == null) {
......
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
mServerSocket = new LocalServerSocket(fd);//创建服务端的Socket
mCloseSocketFd = true;
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
创建的LocalServerSocket就是Server端的socket,会在runSelectLoop中调用LocalServerSocket.accept函数等待AMS连接。
2.2启动SystemServer进程
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
......
try {
......
//请求fork System Server进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
......
//启动SystemServer进程
return handleSystemServerProcess(parsedArgs);
}
return null;
}
2.3fork新进程
runSelectLoop函数开启一个守护线程,等待AMS连接或者求情创建进程
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
while (true) {
......
for (int i = pollFds.length - 1; i >= 0; --i) {
......
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);//等待AMS connect
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);//创建新进程
......
}
} catch (Exception e) {
......
} finally {
......
}
}
}
}
}
acceptCommandPeer
函数最终会调用LocalServerSocket.accept
函数等待AMS连接,当AMS连接成功后会调用processOneCommand
函数创建新进程。
private ZygoteConnection acceptCommandPeer(String abiList) {
try {
return createNewConnection(mServerSocket.accept(), abiList);
} catch (IOException ex) {
throw new RuntimeException(
"IOException during accept()", ex);
}
}
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
......
//fork 进程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
三、时序图
参考资料
https://www.jianshu.com/p/cbc6b84aee08
《Android进阶解密》