(二)Zygote和System进程的启动过程

来源:互联网 发布:疯狂的java讲义百度云 编辑:程序博客网 时间:2024/05/17 07:28

一、启动的大致流程

所有的应用程序和系统服务,都是Zygote负责创建的,Zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。 Zygote会在系统启动时创建一个虚拟机实例。Zygote进程启动完成之后,会将system进程启动起来,以便和系统的关键服务启动起来。例如AMS ContentService 和PMS等。
关注点:
java世界是何时创建的?
Zygote进程是怎样创建的?

二、Zygote的启动过程

1. zygote 的启动脚本
在(一)中1.1.节分析到 init.rc文件解析到一个名字为apppress 的一个service其代码片段如下:
(此段为Native层代码)

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  

代码第二行,表示Zygote进程启动过程中内部创建一个zygote的socket。
运行在System进程中的AMS就是通过这个Socket来请求Zygote创建新的应用程序。

最终执行service_start函数

在中间执行了一系列函数,主要是Socket AMS在请求Zygote创建新的应用程序进程之前,会打开设备文件来连接到Zygote进程的Client端Socket

最终执行到app_process(在Zygote进程中加载应用程序)

2 Zygote进程的启动过程(前6个步骤)

时序图:
时序图

  1. app_process.main 通过对main函数的分析发现是由AppRuntime的start函数来进一步启动的。
  2. 分析AndroidRuntime类的start函数发现参数className=com.android.interna.os.ZygoteInit
    ;参数startSystemServer的值=true.
    而关注点。虚拟机就是在这里创建的!
    这个函数主要做了三件事:
    一、调用函数startVM启动虚拟机
    二、调用了函数StarReg注册了JNI方法
    三、调用了com.androdi.internal.os.ZygoteInit类的main函数至此进入Java世界。

start函数如下:

/* * Start the Android runtime.  This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". */  void AndroidRuntime::start(const char* className, const bool startSystemServer)  {      ......      char* slashClassName = NULL;      char* cp;      JNIEnv* env;      ......      /* start the virtual machine */      if (startVm(&mJavaVM, &env) != 0)          goto bail;      /*     * Register android functions.     */      if (startReg(env) < 0) {          LOGE("Unable to register all android natives\n");          goto bail;      }      /*     * We want to call main() with a String array with arguments in it.     * At present we only have one argument, the class name.  Create an     * array to hold it.     */      jclass stringClass;      jobjectArray strArray;      jstring classNameStr;      jstring startSystemServerStr;      stringClass = env->FindClass("java/lang/String");      assert(stringClass != NULL);      strArray = env->NewObjectArray(2, stringClass, NULL);      assert(strArray != NULL);      classNameStr = env->NewStringUTF(className);      assert(classNameStr != NULL);      env->SetObjectArrayElement(strArray, 0, classNameStr);      startSystemServerStr = env->NewStringUTF(startSystemServer ?          "true" : "false");      env->SetObjectArrayElement(strArray, 1, startSystemServerStr);      /*     * Start VM.  This thread becomes the main thread of the VM, and will     * not return until the VM exits.     */      jclass startClass;      jmethodID startMeth;      slashClassName = strdup(className);      for (cp = slashClassName; *cp != '\0'; cp++)          if (*cp == '.')              *cp = '/';      startClass = env->FindClass(slashClassName);      if (startClass == NULL) {          ......      } else {          startMeth = env->GetStaticMethodID(startClass, "main",              "([Ljava/lang/String;)V");          if (startMeth == NULL) {              ......          } else {              env->CallStaticVoidMethod(startClass, startMeth, strArray);              ......          }      }      ......  }  

3.ZygoteInit 的main函数(JAVA世界的入口)

原创粉丝点击