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

一、启动的大致流程

所有的应用程序和系统服务,都是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个步骤)

时序图:
(二)Zygote和System进程的启动过程_第1张图片

  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世界的入口)

你可能感兴趣的:(Android,底层开发)