Android系统内核初始化完毕后,进入用户空间启动的第一个进程叫init 他是Android系统所有进程的祖先,这个进程启动后会初始化文件系统,然后养育很多娃,比如系统中许许多多的服务,其中有一个服务名字就叫zygote ,zygote 翻译过来其实就叫做受精卵,它应该是init的所有娃中比较特殊的一个,其他的娃多大是一些底层服务,而zygote 这个娃的特殊之处在于它负责启动java虚拟机,并将android带入java的世界中,从此android与众不同,我想这也是android在技术上与其他众多类linux系统的主要差别之一吧!
zygote 在android中具有重要的作用,那么到底有什么用呢??
1.负责启动java虚拟机
2.加载很多需要预加载的类
3.负责启动systemServer ,systemServer 会启动android中的所有服务,基本上完成了上层框架的所有功能。
4.负责初始化新进程,其实就是fork java的独立进程,比如启动一个act,那么zygote 就负责为新启动的act 建立进程,并调用act中的main,或者OnCreate,这样或许大家更容易理解。
但是对于init来说zygote其实就是一个很普通的服务,与他养育的其他娃没有任何差别。请看代码:
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
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
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
因为对于处理器平台来说有32 和64位的差别,我们手里的手机也有这个差别,所有zygote 也是有这个差别的,其实它分为32,64,32_64,64_32,这四种模式,或许有一天会有128,512模式。以上代码就是32_64位模式,主模式是32位,辅助模式是64位,其实这个手机是64位的,但是他支持32位,而这种设置会将大多数应用以32模式运行,但是一些具有特殊要求的应用也会以64位模式运行,这是负责创建进程的将是zygote_secondary。
下面我们来分析一下app_process 这个进程:
app_process 这个进程不仅能启动zygote 而且也是可以启动一个普通的类的,他会根据你参数的不同来实现不同的功能。
-Xzygote 这个参数是传给虚拟机的,并不是传给app_process 的,表示需要重新初始化一个新的jvm
--zygote: 这个参数传给app_process 表示启动zygote 模式。
--start-system-server:这个参数表示启动systemServer 服务。一般情况下,这个参数只有zygote 模式才有,因为其他模式貌似不需要这个东西。
--socket-name=zygote:这个参数表示socket 的名称,因为zygote 启动完毕后,并不会退出,他还负责为其他应用创建进程,ams就是通过这个socket与zygote 通讯来完成进程创建的。
--application:这个其实是另外一种模式的标志,表示启动的为普通应用,
--nice-name= 这个表示创建的进程的名字,zygote 模式没有这个东西。
-classpath 或者-cp 这个为创建普通应用时的class路径,我猜的。
app_process 的main函数主要是对于以上的参数的处理,除了这个之外就是新建APPRuntime类
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
这个类负责启动java的main class
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.");
}
负责初始化zygote 模式的叫ZytoteInit 类,负责初始化其他进程的叫RuntimeInit 类。
其实如果要继续分析的话,则可以沿着这两条线,继续去分析,我想后面会有奇迹等着你哦!
不过我们今天的任务是分析app_process ,另外的交给未来吧!
如果要明白,app_process 如何启动jvm ,如何跳转java层,那么不分析AppRuntime 则是不现实的,估计也就变成徒有其表了。现在我们来分析今天唯一有点难度的AppRuntime
AppRuntime 继承AndroidRuntime ,因为AndroidRuntime 有两个虚函数所以,AppRuntime 主要实现这个两个函数:
/**
* This gets called after the VM has been created, but before we
* run any code. Override it to make any FindClass calls that need
* to use CLASSPATH.
*/
virtual void onVmCreated(JNIEnv* env);
/**
* This gets called after the JavaVM has initialized. Override it
* with the system's native entry point.
*/
virtual void onStarted() = 0;
/**
* This gets called after the JavaVM has initialized after a Zygote
* fork. Override it to initialize threads, etc. Upon return, the
* correct static main will be invoked.
*/
virtual void onZygoteInit() { }
/**
* Called when the Java application exits to perform additional cleanup actions
* before the process is terminated.
*/
virtual void onExit(int /*code*/) { }
从名字我们就应该可以看出来,一个为虚拟机创建完毕后调用,一个为虚拟机启动完毕后调用。
对于AppRuntime 来说,onVmCreated 主要作用是设置主函数名称,onStarted函数为启动事件管理器,并且调用main函数。
对于zygote 模式来说,onVmCreated 无效。
下面我们来看看最重要的那个函数,runtime.start 函数,这个函数主要完成以下任务:
1.初始化jni
2.启动jvm虚拟机
3.注册无数的jni函数
4.启动java类
初始化jni:
主要调用jni_invocation.Init 完成初始化
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
"JNI_GetDefaultJavaVMInitArgs")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
"JNI_GetCreatedJavaVMs")) {
return false;
}
其实主要转换这几个jni函数,这几个jni函数会在创建虚拟机的时候被调用
创建虚拟机主要涉及无数的参数处理,最后调用JNI_CreateJavaVM 完成jvm的创建。
注册jni无数上层java需要调用的jni函数,其实这里负责调用各个jni注册函数。我猜测应该包含了系统初始化阶段所有的jni函数。
调用java类的静态main函数的方法就很通用了。貌似没什么特别的。