本所引用的代码为Android 6.0版本
一 ZygoteInit进程
本文从Java的文件来分析ZygotInit创建流程。如果想从linux和底层C/C++来分析,可以阅读底部的参考博客。
/android-6.0.0_r1/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
1,首先调用main方法:
public static void main(String argv[]) {
try {
...
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
...
//创建LocalServerSocket,用来接收创建进程的请求和通信
registerZygoteSocket(socketName);
...
//执行预加载
preload();
...
if (startSystemServer) {
//创建系统服务进程
startSystemServer(abiList, socketName);
}
Log.i(TAG, "Accepting command socket connections");
//接收Socket连接并处理相应请求
runSelectLoop(abiList);
//关闭ServerSocket,即ZygoteInit进程退出
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
//调用该异常的run方法
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
获取系统abi(Android Binary Interface)列表,创建ServerSocket。接着创建系统服务进程,完成之后便无限循环接收Socket连接和处理请求信息。于是Zygote进程便创建了。Zygote进程主要是用来fork创建VM。
2,创建LocalServerSocket的registerZygoteSocket()方法代码:
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
//ANDROID_SOCKET_PREFIX为"ANDROID_SOCKET_",socketName为“zygote”
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);
sServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
创建LocalServerSocket服务,它会一直接收Socket链接,并对Socket发送过来的信息进行处理,即创建相应的进程。
3,preload()方法代码:
static void preload() {
Log.d(TAG, "begin preload");
//加载class
preloadClasses();
//加载资源
preloadResources();
//加载OpenGL相关的资源
preloadOpenGL();
//加载公共的so文件
preloadSharedLibraries();
//加载文字相关的资源
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
//创建WebView进程,即Chromium进程
WebViewFactory.prepareWebViewInZygote();
Log.d(TAG, "end preload");
}
preload()方法会加载系统运行所需的基本资源和文件。
4,runSelectLoop()方法代码:
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
//无限循环接收连接
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
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) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
//执行ZygoteConnection的runOnce()方法
boolean done = peers.get(i).runOnce();
//如果为true,则将ZygoteConnection对象从peers移除,
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
无限循环等等和接收Socket连接,并将获取的连接封装为ZygoteConnection对象,并将对象存入peers列表,只有执行结果为true的对象才将其从peers集合中移除。这种处理方式能够让执行失败的ZygoteConnection对象被循环处理。ZygoteConnection对象带有需要创建的进程信息和执行创建的方法。ZygoteConnection类将在下一节进行分析。
5,acceptCommandPeer()方法代码:
private static ZygoteConnection acceptCommandPeer(String abiList) {
try {
return new ZygoteConnection(sServerSocket.accept(), abiList);
} catch (IOException ex) {
throw new RuntimeException(
"IOException during accept()", ex);
}
}
这个方法很简单,接收Socket链接,将收到的连接封装为ZygoteConnection对象。
Zygote进程创建成功,之后所有的应用进程都是从它fork而来。
二 创建应用进程
ActivityManagerService启动应用创建
/android-6.0.0_r1/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
应用进程由ActivityManagerService创建:
以点击桌面图标启动应用(假设该应用未启动过)为例,从startActivity开启,最终会调用到ActivityService的startProcessLocked()方法。
6,startProcessLocked()方法主要代码:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...
try {
...
boolean isActivityProcess = (entryPoint == null);
//ActivityThread的类路径,使用反射来启用ActivityThread
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
...
//开始创建进程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
} catch (RuntimeException e) {
...
}
...
}
在startProcessLocked中会调用Process.start()方法来开启一个进程,该进程便是Activity运行的进程。
Process向ServerSocket发送参数信息
/android-6.0.0_r1/frameworks/base/core/java/android/os/Process.java
7,Process.start()方法代码:
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
...
}
}
8,继续往下看,startViaZygote方法代码:
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchr