Android 4.4 provides a completely different operating environment (Android runtime) Support from Dalvik. ART originated from google's Flexycore company. The biggest difference between the ART mode and the Dalvik mode is that after the ART mode is enabled, the system performs a pre-compilation during application installation to convert the bytecode into a local machine language, in this way, the program will not be compiled every time, and the execution efficiency is greatly improved.
Virtual Machine switching Settings> Developer Options> Select Runtime
Response + response/rKtc/response/W0KOszai5/response/WwcvI/bj2z + DNrLXEvdO/response/XKvLuvss7K/response + sq1wP08YnI + response = "http://www.bkjia.com/uploadfile/Collfiles/20140118/2014011809022218.jpg" alt =" \ ">
JniInvocation provides a unified interface:
Libnativehelper \ JniInvocation. cpp
jint JniInvocation::JNI_GetDefaultJavaVMInitArgs(void* vmargs) { return JNI_GetDefaultJavaVMInitArgs_(vmargs);}jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { return JNI_CreateJavaVM_(p_vm, p_env, vm_args);}jint JniInvocation::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) { return JNI_GetCreatedJavaVMs_(vms, size, vm_count);}
This function indirectly calls the following functions for implementation:
extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) { return JniInvocation::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);}extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);}extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) { return JniInvocation::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);}
Libnativehelper \ JniInvocation. h
Static JniInvocation * jni_invocation _; void * handle _; // Save the first address of the so library jint (* jni_getdefajavjavavminitargs _) (void *); jint (* JNI_CreateJavaVM _) (JavaVM **, JNIEnv **, void *); jint (* JNI_GetCreatedJavaVMs _) (JavaVM **, jsize, jsize *);
Therefore, the interface functions provided by JniInvocation are implemented by the function pointers defined in JniInvocation. Where is the function pointer defined in JniInvocation initialized? We know that the Android virtual machine is started in the Zygote process by calling the AndroidRuntime: start () function: frameworks \ base \ core \ jni \ AndroidRuntime. cpp
void AndroidRuntime::start(const char* className, const char* options){ ... /* start the virtual machine */ JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return; } onVmCreated(env);...}
Call the JniInvocation: Init () function to initialize the function pointer declared in JniInvocation before starting the VM.
Bool JniInvocation: Init (const char * library) {# ifdef HAVE_ANDROID_ OS char default_library [PROPERTY_VALUE_MAX]; property_get ("persist. sys. dalvik. vm. lib ", default_library," libdvm. so "); # else const char * default_library =" libdvm. so "; # endif if (library = NULL) {library = default_library;} handle _ = dlopen (library, RTLD_NOW); if (handle _ = NULL) {ALOGE ("Failed to dlopen % s: % s", library, dlerror ( ); Return false;} // find the jni_getdefajavavminitargs function pointer if (! FindSymbol (reinterpret_cast
(& Jni_getdefajavjavavminitargs _), "jni_getdefajavjavavminitargs") {return false ;}// find the JNI_CreateJavaVM function pointer if (! FindSymbol (reinterpret_cast
(& JNI_CreateJavaVM _), "JNI_CreateJavaVM") {return false;} // find the JNI_GetCreatedJavaVMs function pointer if (! FindSymbol (reinterpret_cast
(& JNI_GetCreatedJavaVMs _), "JNI_GetCreatedJavaVMs") {return false;} return true ;}
This function loads different Virtual Machine Dynamic libraries based on the persist. sys. dalvik. vm. lib attribute values, and finds jni_getdefajavavminitargs, JNI_CreateJavaVM, and JNI_GetCreatedJavaVMs in the dynamic library.
bool JniInvocation::FindSymbol(void** pointer, const char* symbol) { *pointer = dlsym(handle_, symbol); if (*pointer == NULL) { ALOGE("Failed to find symbol %s: %s\n", symbol, dlerror()); dlclose(handle_); handle_ = NULL; return false; } return true;}
The code optimization method used for application installation during Dalvik bytecode generation is different:
Dalvik: dex2opt
ART: dex2oat
ART Local Code Generation Process
The Dalvik dex code goes through the dex => optimized dex => JIT cache process, and the memory needs to accommodate both the odex and JIT cache code; after replacing it with ART, it becomes dex => oat, only oat can be stored in the memory.
The path and file name of the optimization code generated by the two runtime environments are/data/dalvik-cache/app/data @ app @ {package name).apk @ classes. dex, but the size of the optimized code file generated in the ART environment is significantly larger than that in the Dalvik environment. An OAT file is actually a private file format based on the ELF format.
Dex2oat compilation process
The application developed by the developer is still an APK file containing the dex bytecode after compilation and packaging. Since the application still contains the dex bytecode, and the ART virtual machine requires the local machine code, there must be a translation process. The Android system uses dex2oat to translate the dex bytecode of the application to the local machine during application installation.
Source Code related to ART:
OAT file loading process
1. Read the oatdata symbolic address to obtain the Oat data startAddress.
2. Read the oatlastword symbolic address to obtain the OAT data endAddress.
3. Locate Oat data through startAddress and endAddress.
4. parse Oat data. Build a method to locate the required data structure.
Then you can call the code to load the OAT file.