接着上一节,继续:
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
......
// 上一节分析内容
mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false),
mSdkVersion, mOnlyCore);
......
// 本节分析内容
// 1
/** * Out of paranoia, ensure that everything in the boot class * path has been dexed. */
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!");
}
// 2
/** * Also ensure all external libraries have had dexopt run on them. */
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.
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
// 3
/** * 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 {
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);
}
}
}
// 4
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();
}
}
}
}
本节最主要的工作是否要对系统库进行dex优化:
1、针对BOOTCLASSPATH路径下的库,具体路径得看脚本文件init.rc:
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar
2、mSharedLibraries是不是很熟悉,第四节有讲到,如果不明白就回到第四节看看就很清楚了,他保存的是platform.xml中声明的系统库信息。
3、system/framework目录下的jar包和apk文件。
4、如果前面1,2,3要dex优化,由 Installer 通 过 socket 将 命 令 传 给 installd 的 run_dexopt, 最 终 调 用 的是/system/bin/dexopt 对 jar包、apk 进行处理。如果已经进行了 dexopt 动作,则将/data/dalvik-cache下的以 data 开头的文件删除,后续重新建立,具体原因(和dalvik运行机制有关)看代码中的注释(考验你的英文时候到了):
// 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.