这道题想考察什么?
- 了解Zygote的作用(初级)
- 熟悉Zygote的启动流程(中级)
- 深刻理解Zygote的工作原理(高级)
---------------------------------------------------------------------------------
【Zygote的作用】
- 启动SystemServer
- 孵化应用进程
(SystemServer用到Zygote准备的资源:常用类、JNI函数、主题资源、共享库)
启动三段式:进程启动 => 准备工作 => LOOP
【Zygote的启动流程】
- init进程fork出zygote进程;——(用execve{Zygote可执行文件的路径})
- 启动虚拟机、注册jni函数;
- 预加载系统资源;——(常用类、JNI函数、主题资源、共享库等,为为孵化应用进程作准备)
- 启动SystemServer;
- 进程Socket Loop
(其中前两点在Native中执行,后三点在Java中执行)
【深刻理解Zygote的工作原理】
Native是如何切换到Java的?实验代码:
int main(int argc, char *argv[]){
JavaVM *jvm;
JNIEnv *env;
JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
jclass class = env->FindClass("ZygoteInit");
jmethodID method = env->GetStaticMethodID(class, "Main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, method, args);
jvm->DestroyJavaVM();
}
SystemServer是如何跟Zygote通信的?
- SystemServer通过Socket与Zygote通信
- Zygote处理SystemServer发来的请求(请求通常是创建新进程并调用ActivityThread.main())
Zygote处理请求的关键代码:
boolean runOnce(){
//读取参数列表,是AMS跨进程发过来的
String[] args = readArgumentList();
//根据参数启动子进程
int pid = Zygote.forkAndSpecialize();
//在子进程中干活:执行Java类的main函数,java类名来自上面读取的参数列表
//其实类名就是ActivityThread
if(pid == 0){
//in child
//由上可知ActivityThread.main()
handleChildProc(args, ...);
return true;
}
}
要注意的细节:
- Zygote fork要单线程 (否则可能会莫名死锁或者状态不一致)
- Zygote的IPC没有采用binder (而是用本地Socket)
【遗留两个问题】:
- 孵化应用进程这种事为什么不交给SystemServer来做,而专门设计一个Zygote?
- Zygote的 IPC通信机制为什么不采用binder?如果采用binder的话会有什么问题?
---------------------------------------------------------------------------------------------------------------------
【Zygote启动源码分析】
init.zygote64.rc启动脚本:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
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
- 这个脚本由init进程解析
- 根据该脚本init将fork一个进程,新进程将运行/system/bin/app_process64
- app_process64的入口函数是/framework/base/cmds/app_process/app_main.cpp::main()
CPP部分:
app_main.cpp::main(){
//创建/data/dalvik-cache/arm64 目录
maybeCreateDalvikCache()
AndroidRuntime.cpp::start("com.android.internal.os.ZygoteInit", ...){
AndroidRuntime.cpp::startVm()
app_main.cpp::AppRuntime.cpp.onVmCreated(){
}
//找到并调用com.android.internal.os.ZygoteInit中的main()方法
char* slashClassName = toSlashClassName("com.android.internal.os.ZygoteInit");
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}}
- 启动虚拟机
- 调用/framework/base/core/java/com/android/internal/os/ZygoteInit.java::main(),从此进入Java世界
Java部分:
ZygoteInit.java.main(){
//if (startSystemServer):
//P1.1: 启动SystemServer
Runnable r = ZygoteInit.java::forkSystemServer(abiList, socketName, zygoteServer){
Zygote.forkSystemServer()
//pid == 0:
ZygoteInit.java::handleSystemServerProcess(){
//P5: 将SystemServer.class传给zygoteInit
ZygoteInit.java::zygoteInit(){
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(){
RuntimeInit.java::findStaticMain(){
//main方法
cl = Class.forName(className, true, classLoader);
m = cl.getMethod("main", new Class[] { String[].class });
new MethodAndArgsCaller(){
//mThread 将保存main()方法
}}}}}}
//MethodAndArgsCaller.run
r.run(){
//实际调用的是SystermServer.java::main()方法
mMethod.invoke(null, new Object[] { mArgs });
}
----------------------------------------------------------
//else:
//P1.2: 启动应用进程
caller = ZygoteServer.java::runSelectLoop(){
//一直等待SystemServer的请求
while(true):
ZygoteConnection.java::processOneCommand(){
//读取参数列表
readArgumentList();
//创建新进程
pid = Zygote.forkAndSpecialize(……)
if pid == 0:
//子进程的处理
handleChildProc(){
//P6: 与P5类似,将ActivityThread .class传给zygoteInit
ZygoteInit.java::zygoteInit()
}
else:
//父进程:也就是Zygote
handleParentProc(){
}
}
//MethodAndArgsCaller.run:
caller.run(){
//实际调用的是ActivityThread.java::main()方法
mMethod.invoke(null, new Object[] { mArgs });
}
}