程序员人生 网站导航

Android Zygote源码分析

栏目:综合技术时间:2015-07-03 08:13:40

目录

  • 目录
  • 概述
  • zygote分析
  • AppRuntime分析
  • 创建虚拟机startVm
  • 注册JNI函数startReg
  • 进入JAVA世界
    • 建立IPC通讯服务端registerZygoteSocket
    • 预加载类和资源preload
    • 启动system_server
    • 有求必应之等待要求runSelectLoop


概述

在Android系统中,所有的利用程序进程,和用来运行系统关键服务的System进程都是由zygote进程负责创建的。因此,我们将它称为进程孵化器。zygote进程是通过复制本身的方式来创建System进程和利用程序进程的。由于zygote进程在启动时会在内部创建1个虚拟机实例,因此,通过复制zygote进程而得到的System进程和利用程序进程可以快速地在内部取得1个虚拟机实例拷贝。
zygote进程在启动完成以后,会马上将System进程启动起来,以便它可以将系统的关键服务启动起来。下面我们将介绍zygote进程的启动脚本,然后分析它和System进程的启动进程。


zygote分析

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

在我之前的1篇博客中已分析了init进程是如何启动service服务了,需要了解的同学可以参考这篇文章:Android init进程――解析配置文件

通过zygote服务的启动脚本,我们可以知道,zygote进程的实际是2进制文件app_process的调用,我们就从这个利用程序的main函数入手去分析1下zygote进程的启动进程,源码以下(/frameworks/base/cmds/app_process/app_main.cpp):

/** * 将-Xzygote加入到JavaVMOption中,返回/system/bin参数指向的下标 */ int AndroidRuntime::addVmArguments(int argc, const char* const argv[]) { int i; for (i = 0; i < argc; i ++) { if (argv[i][0] != '-') { return i; } if (argv[i][1] == '-' && argv[i][2] == 0) { return i + 1; } JavaVMOption opt; memset(&opt, 0, sizeof(opt)); opt.optionString = (char*)argv[i]; mOptions.add(opt); } return i; } int main(int argc, char* const argv[]) { // zygote call parameters // /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server // These are global variables in ProcessState.cpp mArgC = argc; mArgV = argv; mArgLen = 0; for (int i = 0; i < argc; i ++) { mArgLen += strlen(argv[i]) + 1; } // 去除末尾的空格 mArgLen--; AppRuntime runtime; const char* argv0 = argv[0]; // Process command line arguments // ignore argv[0] argc --; argv ++; // Everything up tp '--' or first non '-' arg goes to the vm int i = runtime.addVmArguments(argc, argv); // Parse runtime arguments. Stop at first unrecognized option. bool zygote = false; bool startSystemServer = false; bool application = false; const char* parentDir = NULL; const char* niceName = NULL; const char* className = NULL; while (i < argc) { const char* arg = argv[i ++]; if (!parentDir) { parentDir = arg; } else if (strcmp(arg, "--zygote") == 0) { zygote = true; niceName = "zygote"; } else if (strcmp(arg, "--start-system-server") == 0) { startSystemServer = true; } else if (strcmp(arg, "--application") == 0) { application = true; } else if (strncmp(arg, "--nice-name=", 12)) { niceName = arg + 12; } else { className = arg; break; } } if (niceName && *niceName) { setArgv0(argv0, niceName); set_process_name(niceName); } runtime.mParentDir = parentDir; if (zygote) { // 进入到AppRuntime的start函数 runtime.start("com.android.internal.os.ZygoteInit", startSystemServer? "start-system-server" : ""); } else if (className) { runtime.mClassName = className; runtime.mArgc = argc - i; runtime.mArgv = argv + i; runtime.start("com.android.internal.os.RuntimeInit", application ? "application" : "tool"); } else { fprintf("stderr", "Error: no class name or --zygote supplied. "); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied"); return 10; } }

在zygote的main函数中,通过AppRuntime runtime代码创建了1个AppRuntime对象runtime,接下来Zygote进程就是通过它来进1步启动的。
init.rc中关于启动zygote命令中包括了

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐