一、關(guān)鍵類的介紹
1祠锣、核心類介紹
/frameworks/base/core/java/android/app/ApplicationPackageManager.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java
/frameworks/base/services/core/java/com/android/server/pm/PackageDexOptimizer.java
/frameworks/base/services/core/java/com/android/server/pm/Installer.java
/frameworks/base/services/core/java/com/android/server/pm/Settings.java
/frameworks/base/services/core/java/com/android/server/pm/permission/BasePermission.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
/frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
/frameworks/base/core/java/android/content/pm/IPackageManager.aidl
/frameworks/base/core/java/android/content/pm/PackageManager.java
/frameworks/base/core/java/com/android/server/SystemConfig.java
2淹遵、PackageManager
提供一個(gè)ApplicationInfo的所有信息
提供權(quán)限相關(guān)信息
提供一個(gè)安裝包信息
安裝继找、卸載遂跟、更新app功能
3、Installer :對app進(jìn)行操作
安裝
卸載
更新
遷移
3婴渡、Settings
- 創(chuàng)建”data/system”目錄
- 創(chuàng)建一些xml文件
packages.xml 記錄所有安裝app的信息幻锁,當(dāng)系統(tǒng)進(jìn)行程序安裝、卸載和更新等操作時(shí)边臼,均會更新該文件哄尔。
packages-backup.xml 備份文件
packages-stopped.xml 記錄被用戶強(qiáng)行停止的應(yīng)用的Package信息
packages-stopped-backup.xml 備份文件
packages.list 記錄非系統(tǒng)自帶的APK的數(shù)據(jù)信息,這些APK有變化時(shí)會更新該文件 - 配置相應(yīng)的權(quán)限
- readLPw()函數(shù):
從/data/system/packages.xml或packages-backup.xml文件中獲得packages柠并、permissions相關(guān)信息岭接,添加到相關(guān)內(nèi)存列表中。packages.xml文件記錄了系統(tǒng)的permisssions以及每個(gè)APK的name臼予、codePath鸣戴、flags、version等信息這些信息主要通過APK的AndroidManifest.xml解析獲取粘拾,解析完APK后將更新信息寫入這個(gè)文件窄锅,下次開機(jī)直接從里面讀取相關(guān)信息添加到內(nèi)存相關(guān)結(jié)構(gòu)中。當(dāng)有APK升級缰雇、安裝或刪除時(shí)會更新這個(gè)文件入偷。
- writeLPr函數(shù):
將解析出的每個(gè)APK的配置信息(mSetting.mPackages)保存到packages.xml和packages.list文件追驴。packages.list記錄了如下數(shù)據(jù):pkgName, userId, debugFlag, dataPath(包的數(shù)據(jù)路徑)
4、SystemConfig
通過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中殿雪。
5、DefaultPermissionGrantPolicy
默認(rèn)組件提前授予運(yùn)行時(shí)權(quán)限体捏,DefaultPermissionGrantPolicy在PermissionManagerService的構(gòu)造函數(shù)中被創(chuàng)建冠摄。
6、PackageInstallerService
管理應(yīng)用的安裝過程几缭。
二河泳、PMS初始化
查看系統(tǒng)網(wǎng)址: http://androidxref.com/9.0.0_r3/
1、啟動SystemServer服務(wù)
frameworks/base/services/java/com/android/server/SystemServer.java
/**
* The main entry point from zygote. SystemServer啟動入口
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
.........
// Start services : 分開啟動目的:加快手機(jī)啟動速度
try {
//啟動AMS年栓、PMS拆挥、WMS
startBootstrapServices();
//啟動核心服務(wù)
startCoreServices();
//啟動三方服務(wù)(Launcher啟動)
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
.........
}
private void startBootstrapServices() {
.......
/**
* 以便它有機(jī)會創(chuàng)建關(guān)鍵目錄,如/data/user具有適當(dāng)?shù)臋?quán)限某抓。其他service都會用到此對象
**/
traceBeginAndSlog("StartInstaller"); //加系統(tǒng)日志纸兔,起始位置
Installer installer = mSystemServiceManager.startService(Installer.class);
traceEnd(); // 日志結(jié)束
.......
// Start the package manager. 啟動PMS服務(wù)
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();
......
}
2、初始化PMS
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
- 創(chuàng)建類時(shí)候會把Data分區(qū)一些目錄創(chuàng)建好,比如/data/app否副。
- PackageManagerService構(gòu)造方法
/**
加載類之前在Data分區(qū)創(chuàng)建一些目錄
**/
/**
* Directory where installed applications are stored
*/
private static final File sAppInstallDir =
new File(Environment.getDataDirectory(), "app");
/**
* Directory where installed application's 32-bit native libraries are copied.
*/
private static final File sAppLib32InstallDir =
new File(Environment.getDataDirectory(), "app-lib");
/**
* Directory where code and non-resource assets of forward-locked applications are stored
*/
private static final File sDrmAppPrivateInstallDir =
new File(Environment.getDataDirectory(), "app-private");
//PackageManagerService的入口
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
3汉矿、PMS構(gòu)造方法
- BOOT_PROGRESS_PMS_START : PMS開始掃描安裝的應(yīng)用
UserManagerService :多用戶管理服務(wù)類。主要功能是創(chuàng)建和刪除用戶备禀,以及查詢用戶信息
PermissionManagerService :權(quán)限管理類洲拇。創(chuàng)建PermissionSettings類,它是記錄所有權(quán)限相關(guān)信息
Settings :保存安裝包信息類曲尸。主要涉及/data/system/目錄的packages.xml(逆向工程掣承看文件),packages-backup.xml另患,packages.list纽乱,packages-stopped.xml,packages-stopped-backup.xml等文件昆箕。
PackageDexOptimizer :創(chuàng)建Dex優(yōu)化工具類
PackageHandler : APK的復(fù)制和安裝工作類
public PackageManagerService(Context context, Installer installer,
// Create sub-components that provide services / data. Order here is important.
synchronized (mInstallLock) {
//打印開始階段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis())
........
synchronized (mPackages) {
// Expose private service for system components to use.
LocalServices.addService(
PackageManagerInternal.class, new PackageManagerInternalImpl());
//UserManagerService的主要功能是創(chuàng)建和刪除用戶鸦列,以及查詢用戶信息。
sUserManager = new UserManagerService(context, this,
new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
//PermissionManagerService 權(quán)限管理類鹏倘,創(chuàng)建PermissionSettings類敛熬,它是記錄所有權(quán)限相關(guān)信息
mPermissionManager = PermissionManagerService.create(context,
new DefaultPermissionGrantedCallback() {
@Override
public void onDefaultRuntimePermissionsGranted(int userId) {
synchronized (mPackages) {
mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
}
}
}, mPackages /*externalLock*/);
mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
//它是Android全局管理者,用于協(xié)助PMS保存所有的安裝包信息
mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
}
........
//創(chuàng)建Dex優(yōu)化工具類
mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
"*dexopt*");
// 權(quán)限變化監(jiān)聽器
mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
........
//得到全局系統(tǒng)配置信息第股。
SystemConfig systemConfig = SystemConfig.getInstance();
mAvailableFeatures = systemConfig.getAvailableFeatures();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
........
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
// PMS通過PackageHandler驅(qū)動APK的復(fù)制和安裝工作
mHandler = new PackageHandler(mHandlerThread.getLooper());
mProcessLoggingHandler = new ProcessLoggingHandler();
//mHandler添加到Watchdog的監(jiān)測導(dǎo)致系統(tǒng)卡住
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
mInstantAppRegistry = new InstantAppRegistry(this);
// 通過 systemConfig 獲取系統(tǒng)中的共享庫列表
ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
final int builtInLibCount = libConfig.size();
for (int i = 0; i < builtInLibCount; i++) {
String name = libConfig.keyAt(i);
String path = libConfig.valueAt(i);
//把共享庫寫入系統(tǒng)路徑 L: lock P: packages一系列xml文件 w: write
addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
}
}
}
- BOOT_PROGRESS_PMS_SYSTEM_SCAN_START :PMS掃描/system目錄下的安裝包
app : 存放系統(tǒng)App应民,包括了谷歌內(nèi)置的App也有廠商或者運(yùn)營商提供的App
framework : 存放應(yīng)用框架層的jar包
priv-app: 存放特權(quán)App
lib : 存放so文件
fonts: 存放系統(tǒng)字體文件
media: 存放系統(tǒng)的各種聲音,比如鈴聲、提示音诲锹,以及系統(tǒng)啟動播放的動畫
vendor: 它用來存儲廠商對Android系統(tǒng)的定制部分繁仁。
系統(tǒng)掃描階段的主要工作有以下3點(diǎn):
- 創(chuàng)建/system的子目錄,比如/system/framework归园、/system/priv-app和/system/app等等
- 掃描系統(tǒng)文件黄虱,比如/vendor/overlay、/system/framework庸诱、/system/app等等目錄下的文件捻浦。
- 對掃描到的系統(tǒng)文件做后續(xù)處理。
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
...
//打印掃描系統(tǒng)階段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
startTime);
...
//在/system中創(chuàng)建framework目錄
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
...
//掃描/vendor/overlay目錄下的文件
scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
mParallelPackageParserCallback.findStaticOverlayPackages();
//掃描/system/framework 目錄下的文件
scanDirTracedLI(frameworkDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED,
scanFlags | SCAN_NO_DEX, 0);
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
//掃描 /system/priv-app 目錄下的文件
scanDirTracedLI(privilegedAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
//掃描/system/app 目錄下的文件
scanDirTracedLI(systemAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
File vendorAppDir = new File("/vendor/app");
try {
vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
//掃描 /vendor/app 目錄下的文件
scanDirTracedLI(vendorAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
//掃描/oem/app 目錄下的文件
final File oemAppDir = new File(Environment.getOemDirectory(), "app");
scanDirTracedLI(oemAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
//這個(gè)列表代表有可能有升級包的系統(tǒng)App
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();//1
if (!mOnlyCore) {
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
//這里的mPackages的是PMS的成員變量桥爽,代表scanDirTracedLI方法掃描上面那些目錄得到的
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {//2
...
//將這個(gè)系統(tǒng)App的PackageSetting從PMS的mPackages中移除
removePackageLI(scannedPkg, true);
//將升級包的路徑添加到mExpectingBetter列表中
mExpectingBetter.put(ps.name, ps.codePath);
}
continue;
}
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
...
} else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
//這個(gè)系統(tǒng)App升級包信息在mDisabledSysPackages中,但是沒有發(fā)現(xiàn)這個(gè)升級包存在
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {//5
possiblyDeletedUpdatedSystemApps.add(ps.name);//
}
}
}
}
...
}
- BOOT_PROGRESS_PMS_DATA_SCAN_START:PMS掃描/data目錄下的安裝包
app: 存儲用戶自己安裝的App
data: 存儲所有已安裝的App數(shù)據(jù)的目錄朱灿,每個(gè)App都有自己單獨(dú)的子目錄
app-private: App的私有存儲空間
app-lib: 存儲所有App的Jni庫
system: 存放系統(tǒng)配置文件
anr: 用于存儲ANR發(fā)生時(shí)系統(tǒng)生成的traces.txt文件
掃描Data分區(qū)階段主要做了以下幾件事:
- 掃描/data/app和/data/app-private目錄下的文件。
- 遍歷possiblyDeletedUpdatedSystemApps列表钠四,注釋1處如果這個(gè)系統(tǒng)App的包信息不在PMS的變量mPackages中盗扒,說明是殘留的App信息,后續(xù)會刪除它的數(shù)據(jù)缀去。注釋2處如果這個(gè)系統(tǒng)App的包信息在mPackages中侣灶,說明是存在于Data分區(qū),不屬于系統(tǒng)App缕碎,那么移除其系統(tǒng)權(quán)限褥影。
- 遍歷mExpectingBetter列表,注釋3處根據(jù)系統(tǒng)App所在的目錄設(shè)置掃描的解析參數(shù)咏雌,注釋4處的方法內(nèi)部會將packageName對應(yīng)的包設(shè)置數(shù)據(jù)(PackageSetting)添加到mSettings的mPackages中伪阶。注釋5處掃描系統(tǒng)App的升級包,最后清除mExpectingBetter列表处嫌。
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
...
mSettings.pruneSharedUsersLPw();
//如果沒有加密設(shè)備,那么就開始掃描Data分區(qū)斟湃。
if (!mOnlyCore) {
//打印掃描Data分區(qū)階段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
SystemClock.uptimeMillis());
//掃描/data/app目錄下的文件
scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
//掃描/data/app-private目錄下的文件
scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
| PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
//掃描完Data分區(qū)后熏迹,處理possiblyDeletedUpdatedSystemApps列表
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
// 從mSettings.mDisabledSysPackages變量中移除去此應(yīng)用
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
String msg;
//1:如果這個(gè)系統(tǒng)App的包信息不在PMS的變量mPackages中,說明是殘留的App信息凝赛,后續(xù)會刪除它的數(shù)據(jù)注暗。
if (deletedPkg == null) {
msg = "Updated system package " + deletedAppName
+ " no longer exists; it's data will be wiped";
// Actual deletion of code and data will be handled by later
// reconciliation step
} else {
//2:如果這個(gè)系統(tǒng)App在mPackages中,說明是存在于Data分區(qū)墓猎,不屬于系統(tǒng)App捆昏,那么移除其系統(tǒng)權(quán)限。
msg = "Updated system app + " + deletedAppName
+ " no longer present; removing system privileges for "
+ deletedAppName;
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
}
logCriticalInfo(Log.WARN, msg);
}
//遍歷mExpectingBetter列表
for (int i = 0; i < mExpectingBetter.size(); i++) {
final String packageName = mExpectingBetter.keyAt(i);
if (!mPackages.containsKey(packageName)) {
//得到系統(tǒng)App的升級包路徑
final File scanFile = mExpectingBetter.valueAt(i);
logCriticalInfo(Log.WARN, "Expected better " + packageName
+ " but never showed up; reverting to system");
int reparseFlags = mDefParseFlags;
//3:根據(jù)系統(tǒng)App所在的目錄設(shè)置掃描的解析參數(shù)
if (FileUtils.contains(privilegedAppDir, scanFile)) {
reparseFlags = PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED;
}
...
//將packageName對應(yīng)的包設(shè)置數(shù)據(jù)(PackageSetting)添加到mSettings的mPackages中
mSettings.enableSystemPackageLPw(packageName);//4
try {
//掃描系統(tǒng)App的升級包
scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);//5
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse original system package: "
+ e.getMessage());
}
}
}
}
//清除mExpectingBetter列表
mExpectingBetter.clear();
...
}
- BOOT_PROGRESS_PMS_SCAN_END:PMS掃描結(jié)束
1毙沾、如果當(dāng)前平臺SDK版本和上次啟動時(shí)的SDK版本不同骗卜,重新更新APK的授權(quán)。
2、如果是第一次啟動或者是Android M升級后的第一次啟動寇仓,需要初始化所有用戶定義的默認(rèn)首選App举户。
3、OTA升級后的第一次啟動遍烦,會清除代碼緩存目錄俭嘁。
4、把Settings的內(nèi)容保存到packages.xml中服猪,這樣此后PMS再次創(chuàng)建時(shí)會讀到此前保存的Settings的內(nèi)容供填。
//打印掃描結(jié)束階段日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
Slog.i(TAG, "Time to scan packages: "
+ ((SystemClock.uptimeMillis()-startTime)/1000f)
+ " seconds");
int updateFlags = UPDATE_PERMISSIONS_ALL;
// 如果當(dāng)前平臺SDK版本和上次啟動時(shí)的SDK版本不同,重新更新APK的授權(quán)
if (ver.sdkVersion != mSdkVersion) {
Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
+ mSdkVersion + "; regranting permissions for internal storage");
updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
}
updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
ver.sdkVersion = mSdkVersion;
//如果是第一次啟動或者是Android M升級后的第一次啟動罢猪,需要初始化所有用戶定義的默認(rèn)首選App
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(this, user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
...
//OTA后的第一次啟動近她,會清除代碼緩存目錄。
if (mIsUpgrade && !onlyCore) {
Slog.i(TAG, "Build fingerprint changed; clearing code caches");
for (int i = 0; i < mSettings.mPackages.size(); i++) {
final PackageSetting ps = mSettings.mPackages.valueAt(i);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
}
ver.fingerprint = Build.FINGERPRINT;
}
...
// 把Settings的內(nèi)容保存到packages.xml中
mSettings.writeLPr();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- BOOT_PROGRESS_PMS_READY:PMS就緒
注釋1處創(chuàng)建PackageInstallerService坡脐,PackageInstallerService是用于管理安裝會話的服務(wù)泄私,它會為每次安裝過程分配一個(gè)SessionId。
注釋2處進(jìn)行一次垃圾收集备闲。
注釋3處將PackageManagerInternalImpl(PackageManager的本地服務(wù))添加到LocalServices中晌端,
LocalServices用于存儲運(yùn)行在當(dāng)前的進(jìn)程中的本地服務(wù)。
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
...
mInstallerService = new PackageInstallerService(context, this);//1
...
Runtime.getRuntime().gc();//2
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
FallbackCategoryProvider.loadFallbacks();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
mInstaller.setWarnIfHeld(mPackages);
LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());//3
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
PMS構(gòu)造方法大致流程:
1恬砂、先讀取packages.xml文件內(nèi)容咧纠,解析并保存在成員變量mSettings中。
2泻骤、掃描設(shè)備中的幾個(gè)分區(qū)目錄下的應(yīng)用文件漆羔,把掃描結(jié)果保存到PMS的mPackages中。這記錄的是當(dāng)前系統(tǒng)中的應(yīng)用狀態(tài)信息
3狱掂、后面就是對兩次的應(yīng)用狀態(tài)信息進(jìn)行:比對演痒、重新調(diào)整、掃描特定目錄趋惨。
4鸟顺、最后將應(yīng)用信息重新寫回packages.xml文件
帶學(xué)習(xí):
SystemConfig 對 platform.xml 文件的操作