本文并非从上帝视角来描述PMS的总体设计和运行逻辑,而是记录本人阅读源码的一个过程。分析到后面才会出总结性的文章。
PMS是Android系统中负责安装包管理的服务,它的主要职责如下:
- 管理系统安装的所有应用程序,包括升级、安装、卸载
- 根据Intent匹配相应的Activity、Service、Provider和BroadcastReceiver等,并提供相关信息
- 解析应用权限,在App调用系统接口的时候,检查App是否具有相应的权限
这里所指的PMS包括PackageManagerService服务本身以及PackageManagerService服务运作时使用到的各种其他系统服务。也有人将PackageManagerService简写为PKMS,以和PowerManagerService区分。
PMS服务是在SystemServer进程中启动的,它属于引导服务(Bootstrap service)
看一下PackageManagerService#main
这里主要做了两件事情:
- 创建PackageManagerService并向ServiceManager注册
- 创建PackageManagerNative并向ServiceManager注册
接下来看PackageManagerService的构造方法,PackageManagerService的构造方法非常庞大,但是我们可以把它分为几个阶段:
- 开始阶段:BOOT_PROGRESS_PMS_START
- 系统扫描阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
- Data扫描阶段:BOOT_PROGRESS_PMS_DATA_SCAN_START
- 扫描结束:BOOT_PROGRESS_PMS_SCAN_END
- 就绪阶段:BOOT_PROGRESS_PMS_READY
2.1 BOOT_PROGRESS_PMS_START
接下来来看每个阶段都做了写什么事情,首先是BOOT_PROGRESS_PMS_START
这里主要是对一些属性和子服务进行了创建或赋值,其中比较重要的有mInstaller、mSettings、mPackageDexOptimizer等。在之前的有些版本,mSettings等有些属性是在这里直接new的,而现在采用传入Injector的方式来获取。另外、这里还开启了工作线程。
让我们再来看看Settings#readLPw()都做了什么吧
至此,我们知道,开始阶段BOOT_PROGRESS_PMS_START的主要工作是:
- 初始化PMS的各个子组件/子服务以及相关属性
- 解析package.xml,获取已经安装的App信息,存储到Settings的mPackages中
- 创建了后台工作线程及其Handler
2.2 BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
接下来看看第二阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
可以看出,这里的主要工作是对系统区进行扫描,扫描顺序是OverlayFolder -> frameworkDir -> PrivAppFolder -> AppFolder(),至于为什么这么设计,继续看下去。
先看一下扫面的方法scanDirTracedLI():
这里主要操作如下:
- 通过ParallelPackageParser解析扫描目录下的包
- 取出解析结果,执行addForInitLI
- 删除无效的用户App
这里调用了scanPackageNewLI获取一个ScanResult对象,虽然它也是扫描的意思,但是我们关心的真正的扫描和解析的工作已经在ParallelPackageParser#submit()完成了,所以这里先跳过。
随后又调用了reconcilePackagesLocked方法获取一个Map对象,这里不明白为什么这么做,也打不算去深究。但是不要紧,对主流程没有影响。
最后调用了commitReconciledScanResultLocked()方法,这个方法看名字是提交扫描和解析的结果。看看它的流程吧
这里就比较重要了,它把解析的结果存储到了PMS的各个相关的变量中,后续我们会分析这些变量都用在哪些地方。
我们总结一下BOOT_PROGRESS_PMS_SYSTEM_SCAN_START阶段所做的事情:
- 扫描各个系统分区的的App
- 解析系统App信息
- 把解析结果存储起来,存储在PMS的相关属性和mSettings里
2.3 BOOT_PROGRESS_PMS_DATA_SCAN_START
接下来是BOOT_PROGRESS_PMS_DATA_SCAN_START阶段,扫描/data/app下的App,也就是用户安装的App
2.4 BOOT_PROGRESS_PMS_SCAN_END
接下来看
这里主要做了如下几件事情:
- 如果SDK版本发生了变化(升级系统),重新对App进行授权
- 为系统核心服务准备存储空间
- 如果是升级后第一次正常启动,需要清除代码缓存,但不是会清除应用的配置文件
- 把更新后的信息写回对应的xml文件中
2.5 BOOT_PROGRESS_PMS_READY
这里又对一些属性进行了赋值,最重要的是初始化PackageInstallerService。
2.6 总结
PMS的创建过程分为以下几个阶段
- 开始阶段:BOOT_PROGRESS_PMS_START。这个阶段的主要工作:
- 初始化PMS的各个子组件/子服务以及相关属性
- 解析package.xml,获取已经安装的App信息,存储到Settings的mPackages中
- 创建了后台工作线程及其Handler
- 系统扫描阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START。这个阶段的主要工作:
- 扫描各个系统分区的的App
- 解析系统App信息
- 把解析结果存储起来,存储在PMS的相关属性和mSettings里
- Data扫描阶段:BOOT_PROGRESS_PMS_DATA_SCAN_START。这个阶段对/data/app进行了扫描,主要工作与扫描系统App目录是一样的,只是细节处理上有些不同。初次之外还做了一些扫尾工作。
- 扫描结束:BOOT_PROGRESS_PMS_SCAN_END。这个阶段主要工作:
- 如果SDK版本发生了变化(升级系统),重新对App进行授权
- 为系统核心服务准备存储空间
- 如果是升级后第一次正常启动,需要清除代码缓存,但不是会清除应用的配置文件
- 把更新后的信息写回对应的xml文件中
- 就绪阶段:BOOT_PROGRESS_PMS_READY。这个阶段又对一些属性进行了赋值,最重要的是初始化PackageInstallerService。
这是PMS的主流程,其中有非常多的细节这里没有提及,比如多用户的处理等等。不过有一些细节我也不打算继续深究了,后续会挑一些重要的深入分析。
在SystemServer中,PMS构建完成之后,仍然后一些额外的操作(通过查找mPackageManagerService看它在哪些地方用到了)
在startOtherServices中,PMS做了几件事情:
- 在需要的情况下进行dex优化
- 在需要的情况下进行磁盘清理
- 通知PMS及其子组件系统已就绪
- ActivityManagerService启动Launcher之前等待PMS中为App的启动做好准备工作
这里每一项都可以写一篇文章来介绍,所以这里就暂时略过,只了解大概流程,细节后续再议。
本文分析了PMS创建的主流程,未对分支流程进行太多的探究。总的来说,PMS在SystemServer里面创建,并向ServiceManager注册。其创建过程分为五个阶段,在此过程中会从packages.xml等相关文件中读取上次保存的包列表和实时扫描的列表进行比较和更新,处理升级事宜,最后把更新后的包列表重新持久化。另外,创建完成之后还进行了一些dex优化、磁盘清理等等一些列额外操作。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/8135.html