Zygote进程本身是一个native的程序,在init进程启动后,会执行init.rc中的内容:
service zygote /system/bin/app_process64 -Xzygote
/system/bin -- zygote
--start-system-server --socket-name=zygote
class main
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
writepid /dev/cpuset/foreground/tasks
1.第一行启动native service 名字为 “zygote”
2.关键字class 标示,service的类型是main
3.关键字socket,标示zygote进程会创建一个名称为“zygote”的socket
4.关键字onrestart 表示重启需要执行的命令
Zygote进程对应的主文件是app_main.cpp,当它被启动后会进入app_main.cpp 的main方法:
int main(int argc, char* const argv[]){
......
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
......
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
// 在zygote进程中重新命名进程名
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
// 代表启动SystemServer
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
......
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.");
return 10;
}
}
代码最后会调用runtime的start() 函数,从最初的代码中可以看到runtime是一个AppRuntime对象.
class AppRuntime : public AndroidRuntime
{
......
}
AppRuntime是一个继承于AndroidRuntime,runtime的start()函数将调用到AndroidRuntime::start()函数:
void AndroidRuntime::start(const char* className
, const Vector<String8>& options, bool zygote){
......
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
......
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
.......
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
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
}
}
}
AndroidRuntime 方法中主要做了三件事:
- 调用startVM()启动虚拟机,并且对JNIEnv的指针进行赋值,为注册jni代码做准备;
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
......
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\n");
return -1;
}
.......
}
- 调用startReq()注册JNI方法
/*static*/ int AndroidRuntime::startReg(JNIEnv* env){
ATRACE_NAME("RegisterAndroidNatives");
/*
* This hook causes all future threads created in this process to be
* attached to the JavaVM. (This needs to go away in favor of JNI
* Attach calls.)
*/
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
ALOGV("--- registering native functions ---\n");
/*
* Every "register" function calls one or more things that return
* a local reference (e.g. FindClass). Because we haven't really
* started the VM yet, they're all getting stored in the base frame
* and never released. Use Push/Pop to manage the storage.
*/
env->PushLocalFrame(200);
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);
//createJavaThread("fubar", quickTest, (void*) "hello");
return 0;
}
- 调用ZygoteInit类的main方法,上面代码中className 是由上一步传递过来的"com.android.internal.os.ZygoteInit" toSlashClassName方法是将.置换成/,将className内容替换成了"com/android/internal/os/ZygoteInit"
最终CallStaticVoidMethod调用ZygoteInit main 方法进入java的世界,ZygoteInit中的执行流程,将在
网友评论