zygote 启动
通过 init进程 这篇 我们知道 在解析init.rc时主要做了ServiceManager,zygote的启动
在 init.rc中有一句 import /init.${ro.zygote}.rc 在7.0之后 zygote 分为多个文件
执行时会根据条件执行其中一个我们看zygote32
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
执行zygote文件
-
可看到上面通过app_process 执行了 zygot32文件
-
app_process 一个可执行程序,是通过启动一个Android虚拟机并加载相应的Java类来启动一个进程,其实现代码在app_main.cpp文件中
-
我们来看main函数
-
int main(int argc, char* const argv[]) { //解析运行时参数。在第一个未识别的选项处停止 bool zygote = false; bool startSystemServer = false; bool application = false; String8 niceName; String8 className; ++i; // 跳过未使用的模块 // 根据参数值判断启动zygote 或者application while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { // 启动的是zygote进程 zygote = true; niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { //需要启动SystemServer startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { //启动的是应用进程 application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) { niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } } // 通过AppRuntime.start(AppRuntime继承自AndroidRuntime)启动 zyogte //app_main.cpp在zygote启动其他进程的时候都会通过main()方法 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.");
-
观察上面代码最终通过runtime.start来启动了Zygote
-
AndroidRuntime.start 启动zygote
-
runtime 是AppRunTime 的对象,AppRunTime 继承自AndroidRuntime,所以实际是AndroidRuntime.start启动了zygote
-
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) { //启动虚拟机 if (startVm(&mJavaVM, &env, zygote) != 0) { return; } onVmCreated(env); /* * 通过JNI关联java层,注册android功能。 */ if (startReg(env) < 0) { return; } /* * 启动虚拟机。此线程成为VM的主线程,在VM退出之前不会返回 * slashClassName 为传进来的ZygoteInit * 执行zygoteInit main函数 */ char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); //JNI 调用执行ZygoteInit的main函数 从这开始进入java代码了 env->CallStaticVoidMethod(startClass, startMeth, strArray); }
-
在AndroidRuntime的start方法中
- 调用
startVmVM()
函数启动虚拟机-zygote - 调用
startReg()
函数注册 Android 的 Java 方法,其实在这里就是 JNI 方法 - 调用
CallStaticVoidMethod
执行 Java 类com.android.internal.os.ZygoteInit#main()
方法(Jni实现) - 最终执行了
ZygoteInit#main()
- 调用
执行ZygoteInit#main()
public static void main(String argv[]) {
//1 创建zygoteService
ZygoteServer zygoteServer = new ZygoteServer();
//2 注册并创建名为 zygote 的 LocalServerSocket
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
//3 首次进入 预加载资源
preload(bootTimingsTraceLog);
}
//4 启动SystemServer 通过Zygote.forkSystemService
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
}
//5 启动循环,让上面注册的LocalServerSocket接收AMS的请求
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
}
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
// fullSocketname的值是ANDROID_SOCKET_zygote
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
// 获取Socket名称对应的环境变量
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
// 根据环境变量创建文件描述符
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
// 根据文件描述符创建Socket
mServerSocket = new LocalServerSocket(fd);
}
}
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
//文件描述符列表
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
//socket连接列表
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
// 开启while循环接收请求
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);
}
}
}
}
}
- 上面我们主要关注三件事
- 注册名为 zygote 的 LocalServerSocket 用来接收AMS请求
- 启动SystemServer进程 后面单独说
runSelectLoop
启动循环让上面注册的LocalServerSocket等待接收AMS的请求,在runSelectLoop
- 开启while循环接收ActivityManagerService发送过来的请求
- 当接收到请求之后 ZygoteConnection的runOnce函数来创建一个新的应用程序进程。并在成功创建后将这个连接从Socket连接列表peers和文件描述符列表fds中清除。
- peers.get(i).runOnce(); peers.remove(i); fds.remove(i);
总结
- 通过zygote文件 通知init进程需要执行app_process程序实现代码在
app_main.cpp
中 app_main.cpp
中- 通过AndroidRuntime.start启动zygote
- AndroidRuntime.start中
- 开启虚拟机
- 关键java代码注册android功能
- 执行ZygoteInit.main函数
- 注册名为 zygote 的 LocalServerSocket 用来接收AMS请求
- 启动SystemServer进程
- runSelectLoop启动循环让注册的LocalServerSocket 等待接收Ams的请求
- 到此 zygote 就启动完成,runselectLoop中一直等待,使
zygote
进程持续运行 - 当我们需要启动一个 应用 AMS 会通过 Socket 进程进行 IPC 通信,通知
zygote
进程为这个应用程序创建一个新的进程。