经过看源码DexClassLoader最终会调用DexFile类中的native函数openDexFileNative。
下面来看看openDexFileNative函数做了什么。
openDexFileNative函数在art\runtime\native\dalvik_system_DexFile.cc文件中下面的代码导出了openDexFileNative符号。
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(DexFile, closeDexFile, "(I)V"),
NATIVE_METHOD(DexFile, defineClassNative, "(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;"),
NATIVE_METHOD(DexFile, getClassNameList, "(I)[Ljava/lang/String;"),
NATIVE_METHOD(DexFile, isDexOptNeeded, "(Ljava/lang/String;)Z"),
NATIVE_METHOD(DexFile, openDexFileNative, "(Ljava/lang/String;Ljava/lang/String;I)I"),
};
在DexFile_openDexFileNative函数中,首先调用DexFile::GetChecksum函数获得了zip文件或dex文件的校验和,如果获得校验和成功将校验和保存在局部变量dex_location_checksum中。
DexFile::GetChecksum(dex_location, &dex_location_checksum)
std::string oat_location(outputName.c_str());
dex_file = linker->FindOrCreateOatFileForDexLocation(dex_location, dex_location_checksum, oat_location);
-------------------------------------------------------------------
ClassLinker::FindOrCreateOatFileForDexLocation函数调用了ClassLinker::FindOrCreateOatFileForDexLocationLocked函数。
return FindOrCreateOatFileForDexLocationLocked(dex_location, dex_location_checksum, oat_location);
通过调用ClassLinker::FindDexFileInOatLocation函数判断dex文件是否已经优化为oat文件。
// Check if we already have an up-to-date output file
const DexFile* dex_file = FindDexFileInOatLocation(dex_location,
dex_location_checksum,
oat_location);
GenerateOatFile(dex_location, scoped_flock.GetFile().Fd(), oat_location)
// fork and exec dex2oat
pid_t pid = fork();
execl(dex2oat, dex2oat,
"--runtime-arg", "-Xms64m",
"--runtime-arg", "-Xmx64m",
"--runtime-arg", "-classpath",
"--runtime-arg", class_path,
"--runtime-arg", oat_compiler_filter_option,
#if !defined(ART_TARGET)
"--host",
#endif
boot_image_option,
dex_file_option,
oat_fd_option,
oat_location_option,
NULL);
const DexFile* result = oat_dex_file->OpenDexFile();
至此,完成了dex到oat的转换。