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

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

1、Android架构中的AndroidRuntime

android采用的是层次化系统架构,它的架构图如下:

由架构图可知,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的建立过程分析结束,其时序图如下:

更多相关文章

  1. Android(安卓)WebView详解(二):Android原生与JS互调
  2. 《疯狂Android讲义》学习笔记二
  3. android手势:GestureDetector
  4. Android(安卓)之美 从0到1 之Android(安卓)进阶(二)
  5. 饭后Android(安卓)第六餐-Bmob云后端(Bmob介绍,Android使用方法-增
  6. Android启动过程——init,Zygote,SystemServer
  7. Android之——史上最简单最酷炫的3D图片浏览效果的实现
  8. Android之应用进程模型
  9. 浅析安卓的启动过程

随机推荐

  1. android和ios的系统特性区别
  2. Android编译系统-上
  3. 浅谈Android的Rotation动画的应用
  4. Cocos2d-x在win7下的android交叉编译环境
  5. Android历史版本及和eclipse基本区别
  6. android沉浸式+虚拟按键+Fragment+Coordi
  7. 诚聘Android开发工程师
  8. Android(安卓)Activity 横竖屏模式切换时
  9. android调用第三方库——第四篇——调用
  10. Android - GridView,自定义开关控件,状态选