android源码分析之Runtime的初始化

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


1、Android架构中的AndroidRuntime

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


2、init进程分析

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

//Init.cppint main(int argc, char **argv){    ...    //清除umask默认属性    umask();    add_environment("PATH",_PATH_DEFPATH);    //判断是不是初始化的第一阶段    bool is_first_stage = (arg == 1)||(strcmp(argv[1],"--second-stage")!=0);    if(is_first_stage){        //进行系统文件系统等的挂载        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);    }    open_devull_stdio();    //klog初始化    klog_init();    klog_set_level(KLOG_NOTICE_LEVEL);    if(!is_first_stage){        //关闭/dev/.booting文件的相关权限        close("/dev/.booting",O_WRONLY|O_WCREAT|O_CLOEXEC,000);        //初始化部分属性        property_init();        //先初始化DT,因为DT的属性集的优先级高于comand line        process_kernel_dt();        //处理内核命令行        process_kernel_cmdline;        //导出内核变量        export_kernel_boot_props();    }    ...    //初始化信号量    signal_handler_init();    property_load_boot_defaults();    //开启属性服务    start_property_service();    //解析/init.rc文件    init_parse_config_file(/init.rc);    ... }

此处的代码与android 4.4等,在代码上有略微的差别,但是基本的操作还是一样的,首先进行一些属性的初始化,内核命令行等以及信号量的初始化,最后再启动属性服务以及对init.rc文件进行解析,所以,接下来分析Init.rc文件:

//Init.rcimport /init.environ.rcimport /init.usb.rcimport /init.${ro.hardware}.rcimport /init.${ro.zygote}.rcimport /init.trace.rc...

由代码可知,与android4.4等有明显的差别,此处采用导入.rc文件的方式来初始化相应模块,此处分析zygote模块,对于android6.0来说,它提供了多个zygote相关的.rc文件,有Init.zygote32.rc、Init.zygote32_64.rc、Init.zygote64.rc、Init.zygote64_32.rc等,本文分析Init.zygote32.rc,其他流程是一样的,但是在源码中,只发现了Init.zygote32.rc的相关实现。
看Init.zygote32.rc文件:

//Init.zygote32.rcservice 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

由代码可知,它将会执行/system/bin/app_process,而后面的是它的参数,请注意–zygote和–start-system-server参数,后面将会分析到,而对于/system/bin/app_process的实现app_main.cpp(frameworks/base/cmds/app_process),它的配置在frameworks/base/cmds/app_process目录下的Android.mk文件中:

//Android.mk(frameworks/base/cmds/app_process)LOCAL_PATH = $(call my-dir)app_process_common-shared_libs:=\    libwilhelm\include $(CLEAR_VARS)#看,app_process命令绑定的源码就是该目录下的app_main.cppLOCAL_SRC_FILES:=\    app_main.cpp...

所以,app_process命令绑定的源码实现就是app_main.cpp,在解析Init.zygote32.rc文件的时候,会调用到它的main函数,即app_main.cpp的main函数


3、Android运行时的启动分析

上一节分析了Init进程启动与android运行时的关系,因为对于android运行时的启动来说,它是在Init进程之后,zygote进程启动之后,初始化之前初始化的,所以此时它的入口和zygote的入口一致,即app_main.cpp的main函数,代码如下:

//app_main.cppint main(int argc, char* const argv[]){    ...    //AppRuntime继承自AndroidRuntime    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));    ...    if (zygote) {//如果init.rc配置中有--Zygote,参数为com.android.internal.os.ZygoteInit        runtime.start("com.android.internal.os.ZygoteInit", args);    } else if (className) {//否则参数为com.android.internal.os.RuntimeInit        runtime.start("com.android.internal.os.RuntimeInit", args);    }else{        //显示命令的用法说明        app_usage();    }    ...}

首先创建一个AppRuntime对象,接着调用它的start方法,而此start方法在父类AndroidRuntime中进行了定义,并且此处的参数为com.android.internal.os.ZygoteInit,而对于两种不同的参数而言,只是最后启动的类不一样,如果有–zygote参数,其最后会启动ZygoteInit类,否则就会执行RuntimeInit类,继续追踪start方法。

//AndroidRuntime.cppvoid AndroidRuntime::start(const char* className, const Vector& 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,这里得到的是RuntimeInit.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()的具体代码如下:

//AndroidRuntime.cppint 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调用了,继续看此方法的代码,它的定义出现在DdmConnection的start方法里:

//DdmConnection.cppvoid 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方法。至此,其实Runtime已经初始化完成了。,其时序图如下:
android6.0源码分析之Runtime的初始化_第1张图片


4、非zygote模式的RuntimeInit分析

非zygote模式下,app_process命令行的输入参数没有了–zygote等,所以className变成了com.android.internal.os.RuntimeInit,但是前面的流程还是差不多,只是在AndroidRuntime的start方法中的最后有代码:

//AndroidRuntime.cppvoid AndroidRuntime::start(const char* className, const Vector& options){    ...    //调用上面得到的方法ID和相关参数,这里调用的是RuntimeInit.main();    env->CallStaticVoidMethod(startClass, startMeth, strArray);    ...}

它会根据输入的参数com.android.internal.os.ZygoteInit和RuntimeInit,通过反射以及JNI,找到相应的类,并调用类的main方法,本文是在Init进程中来进行Runtime的初始化并启动Zygote进程(Java域的第一个进程)的,它的启动分析请参考我的文章android6.0源码分析之Zygote进程分析,另外,系统提供app_process的命令,我们可以利用此命令来实现很多供我们自己开发、测试、定制一些特殊的程序,给开发带来了很大的便利。所以,接下来继续分析非zygote模式下的RuntimeInit,首先分析RuntimeInit类的main方法:

//RuntimeInit.javapublic static final void main(String[] argv){    //看到没有,Ddms使能,我们调试时要用到的    enaleDdms();    if(argv.length == 2&&argv[1].equals("application")){        //设置系统输出System.out和System.err的Log Stream        redirectLogStreams();    }else{}    ...    commonInit();    nativeFinishInit();}

commonInit方法主要就是初始化VM里的线程的默认Handler,初始化Log Manager以及一些属性的初始化等,接着看nativeFinishInit方法:

//AndroidRuntime.cppstatic void com_android_internal_os_RuntimeInit_nativeFinishInit(JNIEnv* env,jobject clazz){    gCurRuntime->onStarted();}

onStarted方法的实现在app_main.cpp的AppRuntime类中:

//app_main.cppvirtual void onStarted(){    //在进程中开启线程池    sp<ProcessState> proc = ProcessState::self();    proc->startThreadPool();    //获取运行时对象    AndroidRuntime* ar = AndroidRuntime::getRuntime();    //调用mClassName的main方法    ar->callMain(mClassName,mClass,mArgs);    //停止线程池    IPCThreadState::self()->stopProcess();}

其中最主要的就是callMain的调用:

//AndroidRuntimestatus_t AndroidRuntime::callMain(const String8& className,jclass clazz,const Vector&         args){    ...    env = getJNIEnv();    ...    env.CallStaticVoidMethod(clazz,methodId,strArray);    return NO_ERROR;}

最后,在进行相应的RuntimeInit初始化后,会执行命令中相应测试应用(或命令)的main方法。其时序图如下:
android6.0源码分析之Runtime的初始化_第2张图片


更多相关文章

  1. Android中bindService基本使用方法概述
  2. Unity 编辑器环境下不能正确加载Android Assetbundle 中的 Shade
  3. Android Native进程内存泄露检测
  4. Android webView 获取、设置 cookie的方法
  5. Android常用控件的使用方法
  6. MPAndroidChart的一些问题解决方法

随机推荐

  1. Android Studio导入项目的gradle与studio
  2. Android Calendar一闪而过 无法创建event
  3. invalid resource directory name
  4. Android的SQLite使用实例
  5. Android 进程生命周期(Process Lifecycle
  6. 扔掉USB线,无需无线路由器,利用笔记本电脑(W
  7. IDEA 快捷键 Android Studio快捷键
  8. android中handler用法总结
  9. Android期末项目(一)—— 解析二维数组对象
  10. Android中Thread,hanlder(HanlderThread),Run