Zygote的启动
Android大部分应用程序和系统进程都是通过Zygote来生成的
源码下
/system/core/rootdir/init.rc
import /init.${ro.zygote}.rc #根据32和64位机器区分
其中对init.zygote32.rc分析
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
...
writepid /dev/cpuset/foreground/tasks
从zygote的path可以看出,他所在的程序名叫“app_process”,对整个Android源码搜索找到/frameworks/base/cmds/app_process这个目录下,该目录下的app_main.cpp中main函数可以,通过init.zygote32.rc传递的参数来启动
...... --zygote --start-system-server
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
app_process将启动"ZygoteInit"并且启动system server。runtime实际是一个AndroidRuntime对象,其start在源码/frameworks/base/core/jni/AndroidRuntime.cpp文件中
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
这条语句启动Java虚拟机,启动成功在进入/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中执行。
ZygoteInit.java
public static void main(String argv[]) {
...
//通过上面传进来的参数来设置执行逻辑
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
//注册zygote服务端Socket对象
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
preload(bootTimingsTraceLog);
}
...
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
//
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
...
}
通过main函数可以知道 ZygoteInit利用ZygoteServer为zygote命令连接注册一个服务器套接字,一旦一个程序需要运行时,系统会通过这个Socket在第一时间通知“总管家”,并由它负责实际的进程孵化过程。
从传递的参数来看这些都是执行得
1.预加载虚拟机运行时所需要的各类资源preload(bootTimingsTraceLog);
2.利用UNIX的fork机制SystemServer(下章),从代码上看新建一个专门的进程来承载系统服务的运行。
3.zygoteServer.runSelectLoop这是一个死循环(Socket通信中不陌生),作为zygote的守护主体。
ZygoteServer.java
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.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 {
boolean done = peers.get(i).runOnce(this);
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
网友评论