概述
在Android系统中,所有的应用程序进程,以及用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。由于zygote进程在启动时会在内部创建一个虚拟机实例,因此,通过复制zygote进程而得到的System进程和应用程序进程可以快速地在内部获得一个虚拟机实例拷贝。
zygote进程在启动完成之后,会马上将System进程启动起来,以便它可以将系统的关键服务启动起来。下面我们将介绍zygote进程的启动脚本,然后分析它和System进程的启动过程。
zygote分析
zygote进程的启动脚本如下:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class 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</div>
在我之前的一篇博客中已经分析了init进程是如何启动service服务了,需要了解的同学可以参考这篇文章:Android init进程——解析配置文件
通过zygote服务的启动脚本,我们可以知道,zygote进程的实际是二进制文件app_process的调用,我们就从这个应用程序的main函数入手去分析一下zygote进程的启动过程,源码如下(/frameworks/base/cmds/app_process/app_main.cpp):
/**
* 将-Xzygote加入到JavaVMOption中,返回/system/bin参数指向的下标
*/
int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
{
int i;
for (i = 0; i < argc; i ++) {
if (argv[i][0] != '-') {
return i;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
return i + 1;
}
JavaVMOption opt;
memset(&opt, 0, sizeof(opt));
opt.optionString = (char*)argv[i];
mOptions.add(opt);
}
return i;
}
int main(int argc, char* const argv[])
{
// zygote call parameters
// /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
// These are global variables in ProcessState.cpp
mArgC = argc;
mArgV = argv;
mArgLen = 0;
for (int i = 0; i < argc; i ++) {
mArgLen += strlen(argv[i]) + 1;
}
// 去除末尾的空格
mArgLen--;
AppRuntime runtime;
const char* argv0 = argv[0];
// Process command line arguments
// ignore argv[0]
argc --;
argv ++;
// Everything up tp '--' or first non '-' arg goes to the vm
int i = runtime.addVmArguments(argc, argv);
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
const char* parentDir = NULL;
const char* niceName = NULL;
const char* className = NULL;
while (i < argc) {
const char* arg = argv[i ++];
if (!parentDir) {
parentDir = arg;
} else if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = "zygote";
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12)) {
niceName = arg + 12;
} else {
className = arg;
break;
}
}
if (niceName && *niceName) {
setArgv0(argv0, niceName);
set_process_name(niceName);
}
runtime.mParentDir = parentDir;
if (zygote) {
// 进入到AppRuntime的start函数
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer? "start-system-server" : "");
} else if (className) {
runtime.mClassName = className;
runtime.mArgc = argc - i;
runtime.mArgv = argv + i;
runtime.start("com.android.internal.os.RuntimeInit", application ? "application" : "tool");
} else {
fprintf("stderr", "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied");
return 10;
}
}
</div>
在zygote的main函数中,通过AppRuntime runtime代码创建了一个AppRuntime对象runtime,接下来Zygote进程就是通过它来进一步启动的。
init.rc中关于启动zygote命令中包含了–zygote参数,所以在if(strcmp(arg, “–zygote”) == 0)判断的时候,会将niceName赋值为”zygote”,然后通过set_process_name(niceName)函数将当前进程的名称设置为zygote。这也是为什么调用的脚本为/system/bin/app_process,而进程名为zygote的原因。set_process_name函数的源码如下(/system/core/libcutils/process_name.c):
static const char* process_name = "unknown";
void set_process_name(const char* new_name)
{
if (new_name == NULL) {
return;
}
int len = strlen(new_name);
char* copy = (char*)malloc(len + 1);
strcpy(copy, new_name);
process_name = (const char*) copy;
}
</div>
从init.rc文件中关于zygote进程的配置参数可知,Zygote进程传递给应用程序app_process的启动参数arg还包含一个”–start-system-server”选项。因此,在调用AppRuntime对象runtime的成员函数start时,第二个参数为”start-system-server”,表示zygote进程启动完成之后,需要将system进程启动起来。
AppRuntime分析
AppRuntime类的成员函数start是从父类AndroidRuntime继承下来的,因此,接下来我们就继续分析AndroidRuntime类的成员函数start的实现,函数源码位置:/frameworks/base/core/jni/AndroidRuntime.cpp:
char* AndroidRuntime::toSlashClassName(const char* className)
{
char* result = strdup(className);
for (char* cp = result; *cp != '\0'; cp ++) {
if (*cp == '.') {
*cp = '/';
}
}
return result;
}
/**
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method int the class
* named by "className".
*
* 这两个参数的值分别为:
* const char* className = "com.android.internal.os.ZygoteInit";
* const char* options = "start-system-server";
*/
void AndroidRuntime::start(const char* className, const char* options)
{
ALOGD("\n>>>>> AndroidRuntime START %s <<<<<<\n",
className != NULL ? className : "(unknown)");
/**
* 'startSystemServer == true' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
if (strcmp(options, "start-system-server") == 0) {
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
// 设置ANDROID_ROOT环境变量
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android dose not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 1. 创建虚拟机
if (startVm(&mJavaVM, &env) != 0) {
return;
}
onVmCreated(env);
// 2. 注册JNI函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
jstring optionsStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
// 创建一个有两个元素的String数组,用Java代码表示为:String[] strArray = new String[2];
strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
// 设置第一个元素为"com.android.internal.os.ZygoteInit"
env->SetObjectArrayElement(strArray, 0, classNameStr);
optionsStr = env->NewStringUTF(options);
// 设置第二个元素为"start-system-server"
env->SetObjectArrayElement(strArray, 1, optionsStr);
// 将

