原創(chuàng)內(nèi)容,轉(zhuǎn)載請注明出處,多謝配合。
PackageManagerService(簡稱 PMS),是 Android 系統(tǒng)核心服務(wù)之一,處理包管理相關(guān)的工作,常見的比如安裝、卸載應(yīng)用等。這個系列文章就簡單了解下PMS,只簡單梳理流程,不摳代碼細節(jié),文章牽涉到的源碼來自Android 8.0。
一、ApplicationPackageManager
PMS是系統(tǒng)服務(wù),那么應(yīng)用層肯定有個PackageManager作為binder call client端來供使用,但是這里要注意,PackageManager是個抽象類,一般使用的是它的實現(xiàn)類:ApplicationPackageManager。
PackageManager提供的功能主要包含如下幾點:
- 提供一個應(yīng)用程序的所有信息(ApplicationInfo)。
- 提供四大組件的信息。
- 查詢permission相關(guān)信息。
- 提供包的信息。
- 安裝、卸載APK。
二、PMS初始化
PMS作為系統(tǒng)服務(wù),自然還是在SystemServer中啟動:
frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
…
//啟動installer服務(wù)
Installer installer = mSystemServiceManager.startService(Installer.class);
…
//啟動PMS服務(wù)
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
...
}
private void startOtherServices() {
...
mPackageManagerService.systemReady();
…
}
Installer是一個負責(zé)package安裝、刪除、遷移、更新的系統(tǒng)服務(wù)。
PMS的main方法:
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
//初始化PMS
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
//向ServiceManager注冊服務(wù),將service寫入/dev/binder中
ServiceManager.addService("package", m);
return m;
}
接下來看看PMS的構(gòu)造方法,這部分代碼非常多,主要分5個階段:
PMS_START階段
- 構(gòu)造Settings類:這個是Android的全局管理者,用于協(xié)助PMS保存所有的安裝包信息;
- 保存Installer對象;
- 初始化SystemConfig,獲取系統(tǒng)配置信息,包括全局屬性、groupid以及系統(tǒng)權(quán)限。初始化一些功能類,包括:PackageDexOptimizer (dex優(yōu)化工具類) 、 DexManager(dex管理類)、PackageHandler(建立package相關(guān)操作的消息循環(huán))等;
- 創(chuàng)建data下的各種目錄,比如data/app, data/app-private等。
PMS_SYSTEM_SCAN_START階段
- 通過scanDirTracedLI掃描系統(tǒng)目錄文件,包括:/system/framework 、/system/priv-app 、/system/app 這倆都是放系統(tǒng)app、/vendor/overlay、/vendor/app、oem/app。
PMS_DATA_SCAN_START階段
- 通過scanDirTracedLI掃描/data/app和/data/app-private目錄下的文件。
PMS_SCAN_END階段
- 將上述信息寫回/data/system/packages.xml。
PMS_READY階段
- 創(chuàng)建服務(wù)PackageInstallerService。
三、構(gòu)造函數(shù)中重點模塊解析
3.1 Settings
frameworks/base/services/core/java/com/android/server/pm/Settings.java
Settings的構(gòu)造函數(shù)主要用于創(chuàng)建”data/system”目錄和一些xml文件,并配置相應(yīng)的權(quán)限,其中:
- packages.xml 記錄所有安裝app的信息,當系統(tǒng)進行程序安裝、卸載和更新等操作時,均會更新該文件。
- packages-backup.xml 備份文件
- packages-stopped.xml 記錄被用戶強行停止的應(yīng)用的Package信息
- packages-stopped-backup.xml 備份文件
- packages.list 記錄非系統(tǒng)自帶的APK的數(shù)據(jù)信息,這些APK有變化時會更新該文件
readLPw()函數(shù):
從/data/system/packages.xml或packages-backup.xml文件中獲得packages、permissions相關(guān)信息,添加到相關(guān)內(nèi)存列表中。packages.xml文件記錄了系統(tǒng)的permisssions以及每個APK的name、codePath、flags、version等信息這些信息主要通過APK的AndroidManifest.xml解析獲取,解析完APK后將更新信息寫入這個文件,下次開機直接從里面讀取相關(guān)信息添加到內(nèi)存相關(guān)結(jié)構(gòu)中。當有APK升級、安裝或刪除時會更新這個文件。
writeLPr函數(shù):
將解析出的每個APK的配置信息(mSetting.mPackages)保存到packages.xml和packages.list文件。packages.list記錄了如下數(shù)據(jù):pkgName, userId, debugFlag, dataPath(包的數(shù)據(jù)路徑)。
3.2 SystemConfig
frameworks/base/services/core/java/com/android/server/SystemConfig.java
通過readPermissions解析指定目錄下的xml文件:
- /system/etc/sysconfig
- /system/etc/permissions
- /odm/etc/sysconfig
- /odm/etc/permissions
- /oem/etc/sysconfig
- /oem/etc/permissions
readPermissions函數(shù)最終會調(diào)用readPermissionsFromXml()使用XMLPullParser的方式解析這些XML文件,然后把解析出來的數(shù)據(jù)結(jié)構(gòu)保存到PMS中。
3.3 scanDirTracedLI
這里就是Apk的解析流程,針對的是系統(tǒng)開機時安裝系統(tǒng)應(yīng)用的場景,遍歷對應(yīng)目錄下的所有apk。解析出包信息保存到Package中。

最后總結(jié)整個啟動過程:

參考:
http://liuwangshu.cn/tags/Android%E5%8C%85%E7%AE%A1%E7%90%86%E6%9C%BA%E5%88%B6/
https://maoao530.github.io/2017/01/10/packagemanager/