构造方法代码片段:
{
/*-------------省略部分代码------------*/
/*优化扫描,check是否有需要字节码优化*/
// Set flag to monitor and not change apk file paths when
// scanning install directories.
/*
定义扫描参数
*/
int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
if (mNoDexOpt) {
Slog.w(TAG, "Running ENG build: no pre-dexopt!");
scanMode |= SCAN_NO_DEX;
}
final HashSet<String> libFiles = new HashSet<String>();
/*
/system/framework目录
*/
mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
/*
/data/dalvik-cache目录
*/
mDalvikCacheDir = new File(dataDir, "dalvik-cache");
boolean didDexOpt = false;
/*
Out of paranoia, ensure that everything in the boot class
path has been dexed.
获取java启动类库
*/
String bootClassPath = System.getProperty("java.boot.class.path");
if (bootClassPath != null) {
String[] paths = splitString(bootClassPath, ':');
for (int i=0; i<paths.length; i++) {
try {
/*
是否需要进行字节码优化
*/
if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
libFiles.add(paths[i]);
mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Boot class path not found: " + paths[i]);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
+ e.getMessage());
}
}
} else {
Slog.w(TAG, "No BOOTCLASSPATH found!");
}
/*
Also ensure all external libraries have had dexopt run on them.
platform.xml中声明的系统库,需要check是否需要优化
*/
if (mSharedLibraries.size() > 0) {
Iterator<String> libs = mSharedLibraries.values().iterator();
while (libs.hasNext()) {
String lib = libs.next();
try {
if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
libFiles.add(lib);
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+ e.getMessage());
}
}
}
// Gross hack for now: we know this file doesn't contain any
// code, so don't dexopt it to avoid the resulting log spew.
/*
将framework-res.apk添加到libFiles中,该apk中定义了系统常用的资源和几个重要的Activity,比如长按power后的选择框
*/
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
/*
And there are a number of commands implemented in Java, which
we currently need to do the dexopt on so that they can be
run from a non-root shell.
*/
String[] frameworkFiles = mFrameworkDir.list();
if (frameworkFiles != null) {
for (int i=0; i<frameworkFiles.length; i++) {
File libPath = new File(mFrameworkDir, frameworkFiles[i]);
String path = libPath.getPath();
// Skip the file if we alrady did it.
if (libFiles.contains(path)) {
continue;
}
// Skip the file if it is not a type we want to dexopt.
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
continue;
}
try {
/*
是否需要字节码优化,只要有一个需要优化,didDexOpt设置为true,后续会根据该条件决定是否删除dalvik-cache文件
*/
if (dalvik.system.DexFile.isDexOptNeeded(path)) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);
} catch (IOException e) {
Slog.w(TAG, "Exception reading jar: " + path, e);
}
}
}
/*
前面有做字节码优化,删除缓存文件
*/
if (didDexOpt) {
// If we had to do a dexopt of one of the previous
// things, then something on the system has changed.
// Consider this significant, and wipe away all other
// existing dexopt files to ensure we don't leave any
// dangling around.
String[] files = mDalvikCacheDir.list();
if (files != null) {
for (int i=0; i<files.length; i++) {
String fn = files[i];
if (fn.startsWith("data@app@")
|| fn.startsWith("data@app-private@")) {
Slog.i(TAG, "Pruning dalvik file: " + fn);
(new File(mDalvikCacheDir, fn)).delete();
}
}
}
}
/*是否需要优化扫描完毕*/
<-----省略部分代码----->
}
扫描以下目录,对需要优化的字节码优化
/system/framewords目录
/data/dalvik-cache目录