Zygote进程源码分析之一

Zygote是一个native进程,由init进程以服务的形式启动. zygote是整个系统创建新进程的核心装置。从字面上看,zygote是受精卵的意思,它的主要工作就是进行细胞分裂。zygote进程在内部会先启动Dalvik虚拟机,继而加载一些必要的系统资源和系统类,最后进入一种监听状态。在后续的运作中,当其他系统模块(比如AMS)希望创建新进程时,只需向zygote进程发出请求,zygote进程监听到该请求后,会相应地“分裂”出新的进程,于是这个新进程在初生之时,就先天具有了自己的Dalvik虚拟机以及系统资源。

init.zygote32.rc 文件定义的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
writepid /dev/cpuset/foreground/tasks

app_process源文件位于frameworks\base\cmds\app_process,只有一个app_main.cpp文件。

Zygote进程主要分为2部分,从C++层到Java层。

C++层主要流程:

1,创建AndroidRuntime

2,启动Dalivk虚拟机

3,注册JNI函数

Java层主要流程:

1,创建本地socket

2,预加载系统类和资源

3,启动SystemServer

4,等待socket接入,启动应用进程。

2 C++层

app_main.cpp的main方法如下,

int main(int argc, char* const argv[])
{
    •••
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //创建AppRuntime
    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;
•••
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string()); // 修改进程名为zygote
    }

    if (zygote) { // 启动java类
        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;
    }
}

AppRuntime是一个内部类,继承与系统的AndroidRuntime类,定义如下,

class AppRuntime : public AndroidRuntime

所以实际上,大部分方法都是由AndroidRuntime类完成,首先看看start方法.

1,启动虚拟机

JniInvocation jni_invocation;
    jni_invocation.Init(NULL); //初始化JNI接口
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) { //启动虚拟机
        return;
    }
onVmCreated(env); // 调用子类的onVmCreated方法

2,注册系统的JNI方法

if (startReg(env) < 0) { // 注册系统的JNI方法
        ALOGE("Unable to register all android natives\n");
        return;
    }

3, 调用Zygoteinit的main方法

char* slashClassName = toSlashClassName(className); // 调用Zygoteinit的main方法
    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
        }
    }
    free(slashClassName);

总体流程图如下,

Zygote进程源码分析之一_第1张图片

2.1 创建虚拟机

创建虚拟机没什么好说的,主要是配置相关环境变量,然后创建虚拟机。

if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }

2.2 注册JNI函数

将java函数和native函数连接起来,注册到jni中,这样java和native函数才可以相互调用,畅通无阻。以注册log为例, gMethods函数返回的是一个数组,将log和native中的函数一一对应起来,

static JNINativeMethod gMethods[] = {
    { "isLoggable", "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
{"println_native","(IILjava/lang/String;Ljava/lang/String;)I",
(void*) android_util_Log_println_native },   };

2.3 Zygoteinit

虚拟机创建好了,调用Zygoteinit的main方法终于走到java中了。








你可能感兴趣的:(---【源码解析】,Zygoteinit进程,源码分析,android)