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张图片

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 布局中的android:onClick的使用方法总结
  3. Android之应用进程模型
  4. Android工程手动增加插件包方法
  5. android颜色值的表示方法android:background="#FFFFFFFF"的意思
  6. android设置横屏和竖屏的方法
  7. 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第五

随机推荐

  1. Flex AIR应用拍照功能(Android和IOS版本)
  2. Android 图形密码
  3. Android Studio 错误 com.android.dex.De
  4. Android 获取网络时间
  5. 复选框
  6. Android 图片倒影效果源码
  7. android嵌入式底层开发
  8. 使用Android studio分析内存泄露
  9. The android SDK requaires Android Deve
  10. android调用cocos2dx例子