Android PackageManagerService流程详细分析(六)之优化系统库

接着上一节,继续:

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.
    原文作者:Rjdeng
    原文地址: https://blog.csdn.net/rjdeng/article/details/49678609
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞