1.dex文件转化为oat文件
首先还是看一下讲dex转化成oat文件的代码,前两个参数就是输入的apk文件和输出的oat文件的描述符,后两个参数则是输入的文件路径和输出的文件路径,最后一个就是优化的标志:
static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
const char* output_file_name, const char* dexopt_flags)
{
static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig
char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX];
sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
execl(DEX2OAT_BIN, DEX2OAT_BIN,
zip_fd_arg, zip_location_arg,
oat_fd_arg, oat_location_arg,
(char*) NULL);
ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
}
这里将会执行的时在/system/bin/dex2oat来对apk文件中的class.dex进行优化。这个程序的源代码文件在art/dex2oat/dex2oat.cc文件中,本人水平所限,里面转化的代码有点难看懂,暂时就先放在一边了。
2.JNI_CreateJavaVM
在创建ART虚拟机的过程中会进行第一次的dex到oat文件的转化,这里就先分析一下这个过程以便对整个过程有个基础的了解。在之前分析过的JniInvocation::Init函数中有如下一段代码:
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
"JNI_GetDefaultJavaVMInitArgs")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
"JNI_GetCreatedJavaVMs")) {
return false;
}
return true;
这段代码就是获得创建虚拟机所必须的接口函数指针,而这里的接口则是根据文件中定义klibararyFallback字符串来获取的,kitkat中是libdvm.so,而在最新的5.0 lollipop的代码中可以看到变成了libart.so,也就是说art模式已经成为默认的虚拟机了: