Android系统-包管理机制(一)PMS服务启动
PackageManagerService(简称PMS),是Android系统中核心服务之一,管理着所有跟package相关的工作,常见的比如安装、卸载应用。
SyetemServer处理
SystemServer启动过程中启动服务
frameworks/base/services/java/com/android/server/SystemServer.java
1 | private void run() { |
从上面可以看出,系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,本文要了解的PMS属于引导服务。
引导服务 | 作用 |
---|---|
Installer | 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换、调度。 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService | 用来管理所有显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为系统提供各种感应器服务 |
PackageManagerService | 用来对apk进行安装、解析、删除、卸载等等操作 |
1 | private void startBootstrapServices() { |
PMS
构造方法
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
1 | public static PackageManagerService main(Context context, Installer installer, |
PMS的构造方法一共有700多行,在代码中,将PMS的构造流程分为了5个阶段,每个阶段会使用EventLog.writeEvent打印系统日志。
- BOOT_PROGRESS_PMS_START(开始阶段)
- BOOT_PROGRESS_PMS_SYSTEM_SCAN_START(扫描系统阶段)
- BOOT_PROGRESS_PMS_DATA_SCAN_START(扫描Data分区阶段)
- BOOT_PROGRESS_PMS_SCAN_END(扫描结束阶段)
- BOOT_PROGRESS_PMS_READY(准备阶段)
1、开始阶段
BOOT_PROGRESS_PMS_START
1 | public PackageManagerService(Context context, Installer installer, |
在开始阶段,创建了很多PMS中的关键对象并赋值给PMS中的成员变量
mSettings
用于保存所有包的动态设置。
1 | Settings(Object lock) { |
此处mSystemDir是指目录/data/system
,在该目录有以下5个文件:
文件 | 功能 |
---|---|
packages.xml | 记录所有安装app的信息 |
packages-backup.xml | 备份文件 |
packages-stopped.xml | 记录系统被强制停止的文件 |
packages-stopped-backup.xml | 备份文件 |
packages.list | 记录应用的数据信息 |
mInstaller
Installer继承自SystemService,和PMS、AMS一样是系统的服务(引导服务),PMS很多的操作都是由Installer来完成的,比如APK的安装和卸载。在Installer内部,通过socket与installd通信,(貌似8.0以上改成了IInstalld和installd进行Binder通信),由位于nativie层的installd来完成具体的操作。
systemConfig
用于得到全局系统配置信息。比如系统的权限就可以通过SystemConfig来获取。
mPackageDexOptimizer
Dex优化的工具类。
mHandler(PackageHandler类型)
PackageHandler继承自Handler,PMS通过PackageHandler驱动APK的复制和安装工作。
PackageHandler处理的消息队列如果过于繁忙,有可能导致系统卡住, 因此将它添加到Watchdog的监测集中。
Watchdog主要有两个用途,一个是定时检测系统关键服务(AMS和WMS等)是否可能发生死锁,还有一个是定时检测线程的消息队列是否长时间处于工作状态(可能阻塞等待了很长时间)。如果出现上述问题,Watchdog会将日志保存起来,必要时还会杀掉自己所在的进程,也就是SystemServer进程。
sUserManager(UserManagerService类型)
多用户管理服务。
2、扫描系统阶段
1 | //打印扫描系统阶段日志 |
系统扫描阶段的主要工作有以下3点:
- 创建/system的子目录,比如/system/framework、/system/priv-app和/system/app等等
- 扫描系统文件,比如/vendor/overlay、/system/framework、/system/app等等目录下的文件。
- 对扫描到的系统文件做后续处理。
主要来说第3点,一次OTA升级对于一个系统App会有三种情况:
- 这个系统APP无更新。
- 这个系统APP有更新。
- 新的OTA版本中,这个系统APP已经被删除。
当系统App升级,PMS会将该系统App的升级包设置数据(PackageSetting)存储到Settings的mDisabledSysPackages列表中(具体见PMS的replaceSystemPackageLIF方法),mDisabledSysPackages的类型为ArrayMap<String, PackageSetting>
。mDisabledSysPackages中的信息会被PMS保存到packages.xml中的<updated-package>
标签下(具体见Settings的writeDisabledSysPackageLPr方法)。
注释1处说明这个系统App有升级包,那么就将该系统App的PackageSetting从mDisabledSysPackages列表中移除,并将系统App的升级包的路径添加到mExpectingBetter列表中,mExpectingBetter的类型为ArrayMap<String, File>
等待后续处理。
注释2处如果这个系统App的升级包信息存储在mDisabledSysPackages列表中,但是没有发现这个升级包存在,则将它加入到possiblyDeletedUpdatedSystemApps列表中,意为“系统App的升级包可能被删除”,之所以是“可能”,是因为系统还没有扫描Data分区,只能暂放到possiblyDeletedUpdatedSystemApps列表中,等到扫描完Data分区后再做处理。
3、扫描Data分区阶段
1 | //如果设备没有加密,那么就开始扫描Data分区 |
扫描Data分区阶段主要做了以下几件事:
- 扫描/data/app和/data/app-private目录下的文件。
- 遍历possiblyDeletedUpdatedSystemApps列表,注释1处如果这个系统App的包信息不在PMS的变量mPackages中,说明是残留的App信息,后续会删除它的数据。注释2处如果这个系统App的包信息在mPackages中,说明是存在于Data分区,不属于系统App,那么移除其系统权限。
- 遍历mExpectingBetter列表,注释3处根据系统App所在的目录设置扫描的解析参数,注释4处的方法内部会将packageName对应的包设置数据(PackageSetting)添加到mSettings的mPackages中。注释5处扫描系统App的升级包,最后清除mExpectingBetter列表。
4、扫描结束阶段
1 | //打印扫描结束阶段日志 |
扫描结束结束阶段主要做了以下几件事:
- 如果当前平台SDK版本和上次启动时的SDK版本不同,重新更新APK的授权。
- 如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选App。
- OTA升级后的第一次启动,会清除代码缓存目录。
- 把Settings的内容保存到packages.xml中,这样此后PMS再次创建时会读到此前保存的Settings的内容。
5、准备阶段
1 | //打印准备阶段日志 |
总结
PMS属于引导服务,由SyetemServer启动
PMS启动又分为5个阶段
- BOOT_PROGRESS_PMS_START(开始阶段)
- BOOT_PROGRESS_PMS_SYSTEM_SCAN_START(扫描系统阶段)
- BOOT_PROGRESS_PMS_DATA_SCAN_START(扫描Data分区阶段)
- BOOT_PROGRESS_PMS_SCAN_END(扫描结束阶段)
- BOOT_PROGRESS_PMS_READY(准备阶段)