Zygote是一个native进程,由init进程以服务的形式启动. zygote是整个系统创建新进程的核心装置。从字面上看,zygote是受精卵的意思,它的主要工作就是进行细胞分裂。zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态。在后续的运作中,当其他系统模块(比如AMS)希望创建新进程时,只需向zygote进程发出请求,zygote进程监听到该请求后,会相应地“分裂”出新的进程,于是这个新进程在初生之时,就先天具有了自己的Dalvik虚拟机以及系统资源。
init.zygote32.rc 文件定义的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
writepid /dev/cpuset/foreground/tasks
app_process源文件位于frameworks\base\cmds\app_process,只有一个app_main.cpp文件。
Zygote进程主要分为2部分,从C++层到Java层。
C++层主要流程:
1,创建AndroidRuntime
2,启动Dalivk虚拟机
3,注册JNI函数
Java层主要流程:
1,创建本地socket
2,预加载系统类和资源
3,启动SystemServer
4,等待socket接入,启动应用进程。
2 C++层
app_main.cpp的main方法如下,
int main(int argc, char* const argv[])
{
•••
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //创建AppRuntime
// Process command line arguments
// ignore argv[0]
argc--;
argv++;
•••
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string());
set_process_name(niceName.string()); // 修改进程名为zygote
}
if (zygote) { // 启动java类
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.");
return 10;
}
}
AppRuntime是一个内部类,继承与系统的AndroidRuntime类,定义如下,
class AppRuntime : public AndroidRuntime
所以实际上,大部分方法都是由AndroidRuntime类完成,首先看看start方法.
1,启动虚拟机
JniInvocation jni_invocation;
jni_invocation.Init(NULL); //初始化JNI接口
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) { //启动虚拟机
return;
}
onVmCreated(env); // 调用子类的onVmCreated方法
2,注册系统的JNI方法
if (startReg(env) < 0) { // 注册系统的JNI方法
ALOGE("Unable to register all android natives\n");
return;
}
3, 调用Zygoteinit的main方法
char* slashClassName = toSlashClassName(className); // 调用Zygoteinit的main方法
jclass startClass = env->FindClass(slashClassName);
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");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
总体流程图如下,
2.1 创建虚拟机
创建虚拟机没什么好说的,主要是配置相关环境变量,然后创建虚拟机。
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\n");
return -1;
}
2.2 注册JNI函数
将java函数和native函数连接起来,注册到jni中,这样java和native函数才可以相互调用,畅通无阻。以注册log为例, gMethods函数返回的是一个数组,将log和native中的函数一一对应起来,
static JNINativeMethod gMethods[] = {
{ "isLoggable", "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
{"println_native","(IILjava/lang/String;Ljava/lang/String;)I",
(void*) android_util_Log_println_native }, };
2.3 Zygoteinit
虚拟机创建好了,调用Zygoteinit的main方法终于走到java中了。