Zygote(app_process)相关分析2

在前一篇文章中已经分析了从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 (0 == strcmp("--zygote", arg)) {
            bool startSystemServer = (i < argc) ? 
                    strcmp(argv[i], "--start-system-server") == 0 : 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.
",
                 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.
");
        app_usage();
        return 10;
}


 从代码中可以看出会调用AppRuntime的start函数来完成zygote的启动。

AppRuntime继承自AndroidRuntime分析:(zygote进入java世界)

会调用AndroidRuntime.cpp的start函数。

在这个函数里主要做一下动作,比较简单。

  start():

   设置root目录“/system”

  startVM()

    1. 调用JNI的虚拟机创建函数。

    2. 设置虚拟机的heapsize默认为16MB

   startReg()

    1. 注册JNI函数。

    2. 通过JNI调用com.android.internal.os.ZygoteInit类的main函数。

  zygoteInit相关

    1. 找到zygoteInit类的main函数(java类)

    2. 通过调用CallStaticVoidMethod()进入java世界(ZygoteInit.java的main())

我们看一下代码:

void start(const char* className, const char* options){

       // start the virtual machine
       JNIEnv* env;
       if (startVm(&mJavaVM, &env) != 0) {
              return;
       }

       //register JNI
       if (startReg(env) < 0) {
              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函数

原文地址:https://www.cnblogs.com/hongguang-kim/p/4813708.html