bool
ClassLinker::OpenDexFilesFromOat(const char
*
dex_location, const char
*
oat_location,
std::vector<std::string>
*
error_msgs,
std::vector<const DexFile
*
>
*
dex_files) {
if
(!DexFile::GetChecksum(dex_location, dex_location_checksum_pointer, &checksum_error_msg)) {
...
}
/
/
检查是否我们有一个已经打开的oatfile(内存中)
const OatFile::OatDexFile
*
oat_dex_file
=
FindOpenedOatDexFile(oat_location, dex_location,dex_location_checksum_pointer);
std::unique_ptr<const OatFile> open_oat_file(
oat_dex_file !
=
nullptr ? oat_dex_file
-
>GetOatFile() : nullptr);
/
/
检查是否我们有一个可以使用的的oatfile(磁盘上),通过oat_location字符串
if
(open_oat_file.get()
=
=
nullptr) {
open_oat_file.reset(FindOatFileInOatLocationForDexFile(dex_location, dex_location_checksum,oat_location, &error_msg));
...
needs_registering
=
true;
}
/
/
如果我们有一个oat文件,检查所有包含的multidex文件以确定我们的dex位置
bool
success
=
LoadMultiDexFilesFromOatFile(open_oat_file.get(), dex_location,
dex_location_checksum_pointer,
false, error_msgs, dex_files);
if
(success) {
const OatFile
*
oat_file
=
open_oat_file.release();
/
/
Avoid deleting it.
if
(needs_registering) {
/
/
We opened the oat
file
, so we must register it.
RegisterOatFile(oat_file);
}
return
oat_file
-
>IsExecutable();
}
/
/
如果不是这样(要么没有oat文件,要么不匹配),重新生成并加载oat,通过dex_location字符串
if
(Runtime::Current()
-
>IsDex2OatEnabled() && has_flock && scoped_flock.HasFile()) {
/
/
Create the oat
file
.
open_oat_file.reset(CreateOatFileForDexLocation(dex_location, scoped_flock.GetFile()
-
>Fd(),oat_location, error_msgs));
}
/
/
Failed, bail.art模式下的解析模式,以上都是编译成oat的编译模式
if
(open_oat_file.get()
=
=
nullptr) {
std::string error_msg;
/
/
dex2oat was disabled
or
crashed. Add the dex
file
in
the
list
of dex_files to make progress.
DexFile::
Open
(dex_location, dex_location, &error_msg, dex_files);
error_msgs
-
>push_back(error_msg);
return
false;
}
/
/
Try to load again, but stronger checks.
success
=
LoadMultiDexFilesFromOatFile(open_oat_file.get(), dex_location,
dex_location_checksum_pointer,
true, error_msgs, dex_files);
if
(success) {
RegisterOatFile(open_oat_file.release());
return
true;
}
}