一. PackageManagerService啟動過程分析
PackageManagerService(PMS)主要是管理應用的安裝,卸載,更新,解析以及權限。如果想了解SystemService啟動過程請看這篇文章: Android 源碼分析(六) SystemServer 進程
如果想了解AMS服務分析請看這篇文章: Android源碼分析(十三)ActivityManagerService服務分析
同AMS一樣,PMS也是由SystemServer啟動的.
public final class SystemServer { private PackageManagerService mPackageManagerService; private PackageManager mPackageManager; ... // Start the package manager. //啟動PMS服務 if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_package_manager_init_start", (int) SystemClock.elapsedRealtime()); } traceBeginAndSlog("StartPackageManagerService"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); traceEnd(); if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { MetricsLogger.histogram(null, "boot_package_manager_init_ready", (int) SystemClock.elapsedRealtime()); } ... }
//PackageManagerService 初始化工作 public class PackageManagerService extends IPackageManager.Stub implements PackageSender { public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { // Self-check for initial settings. PackageManagerServiceCompilerMapping.checkProperties(); //構造一個PackageManagerService PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore); m.enableSystemUserPackages(); //添加到ServiceManager ServiceManager.addService("package", m); return m; } public PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { //installer apk的安裝和卸載最終都是調用installd來實現的。 mInstaller = installer; mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, "*dexopt*"); mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); synchronized (mInstallLock) { // writer //環境變量初始化 synchronized (mPackages) { File dataDir = Environment.getDataDirectory(); mAppInstallDir = new File(dataDir, "app"); mAppLib32InstallDir = new File(dataDir, "app-lib"); mAsecInternalPath = new File(dataDir, "app-asec").getPath(); mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); sUserManager = new UserManagerService(context, this, new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); //權限注冊到 package manager,一個權限與幾個組ID對應,當一個APK授予這個權限時,它同屬於這幾個組。 //權限是一個復雜的過程 // Propagate permission configuration in to package manager. ArrayMap<String, SystemConfig.PermissionEntry> permConfig = systemConfig.getPermissions(); //遍歷權限配置文件 for (int i=0; i<permConfig.size(); i++) { SystemConfig.PermissionEntry perm = permConfig.valueAt(i); //拿到權限 BasePermission bp = mSettings.mPermissions.get(perm.name); if (bp == null) { bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); //寫入權限 mSettings.mPermissions.put(perm.name, bp); } if (perm.gids != null) { bp.setGids(perm.gids, perm.perUser); } } } final PackageHandler mHandler; class PackageHandler extends Handler { void doHandleMessage(Message msg) { switch (msg.what) { } } private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { final File[] files = dir.listFiles(); if (ArrayUtils.isEmpty(files)) { Log.d(TAG, "No files in app dir " + dir); return; } ParallelPackageParser parallelPackageParser = new ParallelPackageParser( mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mParallelPackageParserCallback); parallelPackageParser.close(); } File frameworkDir = new File(Environment.getRootDirectory(), "framework"); // Find base frameworks (resource packages without code). scanDirTracedLI(frameworkDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags | SCAN_NO_DEX, 0); // Collected privileged system packages. 系統安裝包 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); scanDirTracedLI(privilegedAppDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); // Collect ordinary system packages. 系統app安裝包 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); scanDirTracedLI(systemAppDir, mDefParseFlags | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); }
PMS里面主要完成以下幾件事。
1、通過installer與installd進行連接,進行安裝卸載應用操作
2、創建PacakageHandler線程,處理外部應用的安裝卸載請求
3、處理系統權限相關配置
4、掃描安裝應用,並解析APK安裝包信息
二.總結
一張圖總結下PMS主要完成的工作,以及對上與PackageManager交互,向下與Installd的控制。
如果想了解桌面Launcher應用啟動app過程,請看這篇文章。 Android 源碼分析(八) Launcher 桌面啟動App過程
最后補充一點,如果想要了解APK的編譯過程,可以進一步去了解Android4.4之后使用的ART,可以與Dalivk對比了解。
給個Dalivk的啟動過程介紹的文章: Android 源碼分析(十) Dalvik 虛擬機創建過程
給個Dalivk的啟動過程介紹的文章: Android 源碼分析(十) Dalvik 虛擬機創建過程