在前一篇文章中已经分析了从init.c到Zygote(app_process)的启动流程。
今天开始分析frameworks/base/cmds/app_process/app_main.cpp。
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
上面的内容会在app_main.cpp中用到。
/*
* 启动zygote的方式为/system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
* 所以 argc == 5
* argv里头存的就是这5个参数argv[0]=="/system/bin/app_process" ,argv[1] == "-Xzygote"....
*/
int main(int argc, const char* const argv[])
{
...
AppRuntime runtime;
... // 这个函数会返回1,表示只处理了-Xzytote这一个参数,所谓的处理实际上就是将这个参数添加到了runtime对象的mOptions 变量中。
int i = runtime.addVmArguments(argc, argv); // Next arg is parent directory
if (i < argc) {
runtime.mParentDir = argv[i++];
} // Next arg is startup classname or "--zygote"
// Process command line arguments if (i < argc) {
arg = argv[i++];
if ( == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0); runtime.mClassName = arg; // Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i; LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
} else {
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
return ;
}
从代码中可以看出会调用AppRuntime的start函数来完成zygote的启动。
AppRuntime继承自AndroidRuntime分析:(zygote进入java世界)
会调用AndroidRuntime.cpp的start函数。
在这个函数里主要做一下动作,比较简单。
start():
设置root目录“/system” startVM() . 调用JNI的虚拟机创建函数。 . 设置虚拟机的heapsize默认为16MB startReg() . 注册JNI函数。 . 通过JNI调用com.android.internal.os.ZygoteInit类的main函数。 zygoteInit相关 . 找到zygoteInit类的main函数(java类) . 通过调用CallStaticVoidMethod()进入java世界(ZygoteInit.java的main())
我们看一下代码:
void start(const char* className, const char* options){ // start the virtual machine
JNIEnv* env;
if (startVm(&mJavaVM, &env) != ) {
return;
} //register JNI
if (startReg(env) < ) {
return;
} // jni 调用java的main方法
jmethodID startMeth = env->GetStaticMethodID(startClass,
"main","([Ljava/lang/String;)V"); // jni调用找出ZygoteInit类
jclass startClass = env->FindClass(className);
// 运行ZygoteInit类的main函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
在下一节我们继续分析com.android.internal.os.ZygoteInit类的main函数。