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.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章