android6.0源码分析之AndroidRuntime的建立过程

android源码分析之AndroidRuntime的建立过程

android运行时作为android架构的一部分,起着非常重要的作用,它和核心库(Core Libraries)组成了Android运行时库层。本文将依据android源码对AndroidRuntime(android运行时)的建立过程进行分析。

1、Android架构中的AndroidRuntime

android采用的是层次化系统架构,它的架构图如下:
android6.0源码分析之AndroidRuntime的建立过程_第1张图片
由架构图可知,AndroidRuntime处于Linux内核层以及应用框架层中间,而Java的运行环境依赖于Java虚拟机,所以AndroidRuntime对于android系统非常重要。Init进程是Linux环境下非常重要的一个进程,而Zygote进程是Java环境下的第一个进程,所有其他的Java环境下的进程都是由Zygote进程来进行fork的,而init进程在启动Zygote进程之前,会先进行AndroidRuntime的启动和环境建立,下文将对此过程进行详细分析。

2、init进程分析

init进程作为linux启动过程中的一个重要的进程,它主要负责文件系统的挂载,属性的初始化,各种配置的加载启动以及Action触发,Service的启动,而Zygote作为Java环境下的服务进程,也在Init.rc中进行了配置,而init进程是由main函数进行触发的,其main函数如下:

int main(int argc, char **argv){
    ...
    //创建并挂载了一些基本的系统文件
    mkdir("/dev", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mount("devpts", "/dev/pts", "devpts", 0, NULL);
    mount("proc", "/proc", "proc", 0, NULL);
    mount("sysfs", "/sys", "sysfs", 0, NULL);
    ...
    //初始化了部分属性
    property_init();
    ...
 }

而Zygote进程在init.rc文件中的配置如下:

    service zygote /system/bin/app_process -Xzygote /system/bin 
        --zygote --start-system-server
    class main
    socket zygote stream 660 root system

所以,当Linux的Init进程对init.rc文件进行解析加载的时候,会启动此Zygote服务进程。

3、Android运行时的启动分析

Init进程启动Zygote进程的入口为app_main.cpp中的main函数,代码如下:

int main(int argc, char* const argv[]){
    ...
    //AppRuntime继承自AndroidRuntime
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ...
    if (zygote) {//如果init.rc配置中有--Zygote,则启动ZygoteInit
        runtime.start("com.android.internal.os.ZygoteInit", args);
    } else if (className) {//否则RuntimeInit启动
        runtime.start("com.android.internal.os.RuntimeInit", args);
    }
    ...
}

首先创建一个AppRuntime对象,接着调用它的start方法,而此start方法在父类AndroidRuntime中进行了定义,并且此处的参数为com.android.internal.os.ZygoteInit,继续追踪start方法。

void AndroidRuntime::start(const char* className, const Vector<String8>& options){
    ...
    //启动虚拟机
    if (startVm(&mJavaVM, &env) != 0) {
        return;
    }
    //模板方法模式,只是为了创建VM之后释放slashClassName的内存
    onVmCreated(env);
    //注册Android JNI函数
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    ...
    //解析类名
    char* slashClassName = toSlashClassName(className);
    //找到需要启动的java类
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
        //得到指定类中指定方法的ID,这里得到的是ZygoteInit.main()的方法ID
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            //调用上面得到的方法ID和相关参数,即调用Java类ZygoteInit.main();
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
            ...
        }
    }
    ...
}

首先分析Java虚拟机的启动:由以上代码可知,在start方法中,调用startVm()方法进行虚拟机的启动,startVm()的具体代码如下:

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
    ...
    //读取第一个参数指定的属性操作到buffer,并设置默认的参数
    parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf,
         "-Xstacktracefile:");
    ...
    //添加相应的handler操作
    addOption("exit", (void*) runtime_exit);
    ...
    //读取作为dex2oat compiler运行时操作
    parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,
        "--instruction-set-variant=", "-Xcompiler-option");
    // 拷贝特性
    sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set);
    parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,
                        "--instruction-set-features=", "-Ximage-compiler-option");
    parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,
                        "--instruction-set-features=", "-Xcompiler-option");
    ...
    //初始化虚拟机
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }
    ...
}

由代码可知:首先进行一系列的属性读取到buffer的操作,如JIT相关的options,DexClassLoader的相关options等,并将其添加到操作数组容器里面,最后再调用JNI_CreateJavaVM方法进行VM的创建,继续看JNI_CreateJavaVM方法的代码,它的定义出现在DdmConnection的start方法里:

void DdmConnection::start(const char* name) {
    ...
    //定义JNI_CreateJavaVM方法
    jint (*JNI_CreateJavaVM)(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
    //从libart_dso库中解析JNI_CreateJavaVM方法
    JNI_CreateJavaVM = reinterpret_cast<decltype(JNI_CreateJavaVM)>(
            dlsym(libart_dso, "JNI_CreateJavaVM"));
    //定义registerNatives方法
    jint (*registerNatives)(JNIEnv* env, jclass clazz);
    //从libandroid_runtime_dso库中解析registerNatives方法
    registerNatives = reinterpret_cast<decltype(registerNatives)>(
            dlsym(libandroid_runtime_dso,
                "Java_com_android_internal_util_WithFramework_registerNatives"));

    ...
}

JNI_CreateJavaVM方法是从libart_dso库中解析得到的,同样后面要用到的registerNatives方法从事libandroid_runtime_dso库中解析得到的,而这两个库也是在DdmConnection的start方法中打开的,代码如下:

void* libart_dso = dlopen("libart.so", RTLD_NOW);
ALOGE_IF(!libart_dso, "DdmConnection: %s", dlerror());
void* libandroid_runtime_dso = dlopen("libandroid_runtime.so", RTLD_NOW);
ALOGE_IF(!libandroid_runtime_dso, "DdmConnection: %s", dlerror());

而当JNI_CreateJavaVM函数执行成功后,当前本地线程已经把自己的控制权交给JVM,而具体的JNI_CreateJavaVM方法的实现在libart_dso库中,此处不做深究。至此,成功创建了Java虚拟机,而startVm方法也分析结束。

接着分析onVmCreated方法,它使用的是模板方法的设计模式,在androidRuntime中声明并使用,而具体的实现在appRuntime子类中进行,其代码如下:

virtual void onVmCreated(JNIEnv* env){
    if(mClassName.isEmpty()){
        return;//Zygote.Nothing to do here
    }
    char* slashClassName = toSlashClassName(mClassName.string());
    mClass = env->FndClass(slashClassName);
    if(mClass == NULL){
        ALOGE("ERROR:could not find class '%s'\n",mClassName.string);
    }
    free(slashClassName);
    mClass = reinterpret<jclass>(env->NewGlobalRef(mClass));
}

只是简单根据类名获取了类,并释放了类名,所以此处不做过多的分析,接下来分析startReg()方法,方法定义代码如下:

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);
    ...
}

startReg方法主要的作用是进行android JNI函数的注册,从代码可知:它调用函数register_jni_procs()方法将gRegJNI中的方法注册到虚拟机,而gRegJNI中的Native方法如下:

static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_com_android_internal_os_RuntimeInit),
    REG_JNI(register_android_os_SystemClock),
    REG_JNI(register_android_util_EventLog),
    REG_JNI(register_android_util_Log),
    REG_JNI(register_android_content_AssetManager),
    REG_JNI(register_android_content_StringBlock),
    REG_JNI(register_android_content_XmlBlock),
    REG_JNI(register_android_emoji_EmojiFactory),
    REG_JNI(register_android_text_AndroidCharacter),
    REG_JNI(register_android_text_StaticLayout),
    REG_JNI(register_android_text_AndroidBidi),
    REG_JNI(register_android_view_InputDevice),
    REG_JNI(register_android_view_KeyCharacterMap),
    REG_JNI(register_android_os_Process),
    REG_JNI(register_android_os_SystemProperties),
    REG_JNI(register_android_os_Binder),
    REG_JNI(register_android_os_Parcel),
    REG_JNI(register_android_nio_utils),
    REG_JNI(register_android_graphics_Graphics),
    REG_JNI(register_android_view_DisplayEventReceiver),
    REG_JNI(register_android_view_RenderNode),
    REG_JNI(register_android_view_RenderNodeAnimator),
    REG_JNI(register_android_view_GraphicBuffer),
    REG_JNI(register_android_view_DisplayListCanvas),
    REG_JNI(register_android_view_HardwareLayer),
    REG_JNI(register_android_view_ThreadedRenderer),
    REG_JNI(register_android_view_Surface),
    REG_JNI(register_android_view_SurfaceControl),
    REG_JNI(register_android_view_SurfaceSession),
    REG_JNI(register_android_view_TextureView),
                              REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
    REG_JNI(register_com_google_android_gles_jni_EGLImpl),
    REG_JNI(register_com_google_android_gles_jni_GLImpl),
    REG_JNI(register_android_opengl_jni_EGL14),
    REG_JNI(register_android_opengl_jni_EGLExt),
    REG_JNI(register_android_opengl_jni_GLES10),
    REG_JNI(register_android_opengl_jni_GLES10Ext),
    REG_JNI(register_android_opengl_jni_GLES11),
    REG_JNI(register_android_opengl_jni_GLES11Ext),
    REG_JNI(register_android_opengl_jni_GLES20),
    REG_JNI(register_android_opengl_jni_GLES30),
    REG_JNI(register_android_opengl_jni_GLES31),
    REG_JNI(register_android_opengl_jni_GLES31Ext),

    REG_JNI(register_android_graphics_Bitmap),
    REG_JNI(register_android_graphics_BitmapFactory),
    REG_JNI(register_android_graphics_BitmapRegionDecoder),
    REG_JNI(register_android_graphics_Camera),
    REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
    REG_JNI(register_android_graphics_Canvas),
    REG_JNI(register_android_graphics_CanvasProperty),
    REG_JNI(register_android_graphics_ColorFilter),
    REG_JNI(register_android_graphics_DrawFilter),
    REG_JNI(register_android_graphics_FontFamily),
    REG_JNI(register_android_graphics_Interpolator),
    REG_JNI(register_android_graphics_LayerRasterizer),
    REG_JNI(register_android_graphics_MaskFilter),
    REG_JNI(register_android_graphics_Matrix),
    REG_JNI(register_android_graphics_Movie),
    REG_JNI(register_android_graphics_NinePatch),
    REG_JNI(register_android_graphics_Paint),
    REG_JNI(register_android_graphics_Path),
    REG_JNI(register_android_graphics_PathMeasure),
    REG_JNI(register_android_graphics_PathEffect),
    REG_JNI(register_android_graphics_Picture),
    REG_JNI(register_android_graphics_PorterDuff),
    REG_JNI(register_android_graphics_Rasterizer),
    REG_JNI(register_android_graphics_Region),
    REG_JNI(register_android_graphics_Shader),
    REG_JNI(register_android_graphics_SurfaceTexture),
    REG_JNI(register_android_graphics_Typeface),
    REG_JNI(register_android_graphics_Xfermode),
    REG_JNI(register_android_graphics_YuvImage),
    REG_JNI(register_android_graphics_pdf_PdfDocument),
    REG_JNI(register_android_graphics_pdf_PdfEditor),
    REG_JNI(register_android_graphics_pdf_PdfRenderer),

    REG_JNI(register_android_database_CursorWindow),
    REG_JNI(register_android_database_SQLiteConnection),
    REG_JNI(register_android_database_SQLiteGlobal),
    REG_JNI(register_android_database_SQLiteDebug),
    REG_JNI(register_android_os_Debug),
    REG_JNI(register_android_os_FileObserver),
    REG_JNI(register_android_os_MessageQueue),
    REG_JNI(register_android_os_SELinux),
    REG_JNI(register_android_os_Trace),
    REG_JNI(register_android_os_UEventObserver),
    REG_JNI(register_android_net_LocalSocketImpl),
    REG_JNI(register_android_net_NetworkUtils),
    REG_JNI(register_android_net_TrafficStats),
    REG_JNI(register_android_os_MemoryFile),
    REG_JNI(register_com_android_internal_os_Zygote),
    REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
    REG_JNI(register_android_hardware_Camera),
    REG_JNI(register_android_hardware_camera2_CameraMetadata),
    REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice),
    REG_JNI(register_android_hardware_camera2_legacy_PerfMeasurement),
    REG_JNI(register_android_hardware_camera2_DngCreator),
    REG_JNI(register_android_hardware_Radio),
    REG_JNI(register_android_hardware_SensorManager),
    REG_JNI(register_android_hardware_SerialPort),
    REG_JNI(register_android_hardware_SoundTrigger),
    REG_JNI(register_android_hardware_UsbDevice),
    REG_JNI(register_android_hardware_UsbDeviceConnection),
    REG_JNI(register_android_hardware_UsbRequest),
    REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),
    REG_JNI(register_android_media_AudioRecord),
    REG_JNI(register_android_media_AudioSystem),
    REG_JNI(register_android_media_AudioTrack),
    REG_JNI(register_android_media_JetPlayer),
    REG_JNI(register_android_media_RemoteDisplay),
    REG_JNI(register_android_media_ToneGenerator),

    REG_JNI(register_android_opengl_classes),
    REG_JNI(register_android_server_NetworkManagementSocketTagger),
    REG_JNI(register_android_ddm_DdmHandleNativeHeap),
    REG_JNI(register_android_backup_BackupDataInput),
    REG_JNI(register_android_backup_BackupDataOutput),
    REG_JNI(register_android_backup_FileBackupHelperBase),
    REG_JNI(register_android_backup_BackupHelperDispatcher),
    REG_JNI(register_android_app_backup_FullBackup),
    REG_JNI(register_android_app_ActivityThread),
    REG_JNI(register_android_app_NativeActivity),
    REG_JNI(register_android_view_InputChannel),
    REG_JNI(register_android_view_InputEventReceiver),
    REG_JNI(register_android_view_InputEventSender),
    REG_JNI(register_android_view_InputQueue),
    REG_JNI(register_android_view_KeyEvent),
    REG_JNI(register_android_view_MotionEvent),
    REG_JNI(register_android_view_PointerIcon),
    REG_JNI(register_android_view_VelocityTracker),

    REG_JNI(register_android_content_res_ObbScanner),
    REG_JNI(register_android_content_res_Configuration),

    REG_JNI(register_android_animation_PropertyValuesHolder),
    REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
    REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
};

由上可知,在系统建立androidRuntime的时候,创建Java虚拟机,并将系统中一些JNI函数注册到Java虚拟机中,此后只需要通过JNI的方法就可以调用这些Native方法,此外JNI函数的注册还有一种方法,即通过静态代码块System.LoadLibrary(“…”);来加载自定义的JNI方法。

最后,在androidRuntime的start方法中,会通过输入的类名com.android.internal.os.ZygoteInit找到ZygoteInit类,并调用ZygoteInit类的main方法,从而真正由创建虚拟机进入到真正的创建Zygote进程的流程中。至此,androidRuntime的建立过程分析结束,其时序图如下:
android6.0源码分析之AndroidRuntime的建立过程_第2张图片

你可能感兴趣的:(源码,android,jni,android-Ru,android运行时)