什么是 zygote 进程
我们知道 Android 系统中用户空间的第一个进程是 init, 而 init 进程的部分工作就是创建 zygote 进程。 在 Android 系统中,所有应用程序的进程以及系统服务进程 SystemServer 都是由 zygote 进程来完成的。所以 Zygote 也被称之为受精卵进程,因为它完成了很多孵化操作,由此可见 zygote 在 Android 系统中的地位非同一般。
init.rc
Android 系统启动后会创建 init 进程,它的目录在 system/core/init/init.cpp 在这里会进行启动属性服务(propert)以及解析 init.rc 文件,init.rc 是 Android 系统配置的配置文件,其文件目录为 system/core/rootdir/init.rc , 在 init.rc 文件中第12行 import /init.${ro.zygote}.rc 引入了zygote.rc。查看同目录下的 init.zygote32.rc 代码如下:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main # 指的是 zygote 的 class name 为 main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
其中第一行解释如下: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
- service: 启动一个服务
- zygote: 进程名称
- /system/bin/app_process: 二进制执行文件路径
- -Xzygote /system/bin --zygote --start-system-server: 传递的参数
Service 命名会促使 init 进程调用 fork 函数来创建一个新的进程,这里 Service 通知 init 进程创建一个名为 zygote 的进程,而这个进程的可执行程序路径为 syste/bin/app_process, 后面则是执行 app_process 时需要传递的参数。
app_process 是一个可执行程序,我们需要进一步查找 app_process 的源码存放路径,我们知道在 Framework 中二进制文件需要经过 make 编译来生成,而 make 的目标文件 Android.mk/bp 中 可以定义 app_process, 我们通过 grep app_process ./ -rn 就能查找到 app_process 在 frameworks/base/cmds/app_process/Android.mk 中有定义, 这样我们就找到了 app_process 的源码存放路径。
zogote 的执行程序源码是 frameworks/base/cmds/app_process/ , 在 main 函数中会调用 runtime.start 来启动 zygote。
int main(int argc, char* const argv[])
{
……
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
……
}
这里的 runtime 其实就是 AppRuntime,而 AppRuntime 继承至 AndroidRuntime,main 方法中的 start 函数执行的就是 AndroidRuntime 中的 start。
framewords/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const char* options)
{
……
JNIEnv* env;
if (startVm(&mJavaVM, &env) != 0) {//启动虚拟机
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) {//在虚拟机中注册function
ALOGE("Unable to register all android natives\n");
return;
}
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);//找到ZygoteInit类
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");//调用静态main方法
}
}
Zygote 进程在启动的时候会创建 JVM,因此通过 fork 创建的应用程序和 SystemServer 进程可以在内部获取一个 JavaVM 的实例。在启动 Zygote 的时候传过来的类为 com.android.internal.os.ZygoteInit , 在这里通过反射的方式条用其 main 函数进一步完成启动初始化的过程。
// 在AndroidRuntime 的 start 方法通过反射调用的
public static void main(String argv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
// 注册zygote本地Socket服务 监听来自AMS的创建应用进程请求
registerZygoteSocket();
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
// 预加载 一些资源,类等
preload();
……
// "start-system-server" 是上面 runtime.start 传递的参数
if (argv[1].equals("start-system-server")) {
// 启动SystemServer进程
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
// 等待客户端消息
runSelectLoop();
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
到这一步我们可以看到在 Zygote 的初始化中, 主要做了以下几件事情:
- 通过
registerZygoteSocke创建 Zygote 的 Socket 服务,它是一个 LocalSocketServer , 用来等待 ActivityMangerServer 请求 Zygote 创建应用进程的请求。 - 监听 Socket 服务器,等待 ActivityManagerServer 创建的应用进程的请求。
- 创建 SystemServer 进程。