外观
PMS 怎样知道装了哪些应用、一个 Intent 能打开谁?
标准回答
这里的 PMS 指 PackageManagerService。它负责包管理相关状态与查询,并与安装、权限等组件协作,管理应用包、版本、签名、声明的组件及其用户状态。可以把它理解成系统的应用名册和组件索引。
安装 APK 时,系统需要解析 Manifest 等信息,校验包和签名关系,登记 Activity、Service、Receiver、Provider 等组件及相关声明。实际文件操作和权限管理还有其他系统组件参与,不能把安装到运行的全部行为都归给 PMS。
启动 Activity 时,显式 Intent 指定组件,隐式 Intent 则需要按 action、category、data 等规则匹配候选;系统还会考虑可用状态、访问条件和相应策略。包管理提供目标信息,随后由 ATMS 等处理启动、任务与生命周期。PMS 不负责执行目标 Activity 的 onCreate。
应用侧使用 PackageManager 查询信息,但查询结果还受包可见性、目标用户和组件状态影响。查不到某个包,不一定证明设备没有安装;找到目标组件,也不代表当前调用者在任何环境下都能启动它。
关键机制
- 包管理回答“装了什么、声明了什么、当前状态如何”。
- Intent 解析查找候选;真正启动还要经过权限、任务与运行条件检查。
- Manifest 声明权限与实际获得授权不是同一件事。
通俗例子
主用户能打开的页面,在另一个用户空间提示找不到:先确认该用户是否安装或启用了对应组件、调用使用的是哪个用户,再检查 Intent 与访问条件,不能只比对 APK 文件。
追问与回答
显式 Intent 就一定能启动吗?
不能。组件可能不存在、被禁用,目标应用在当前用户下不可用,或者调用方缺少访问权限;跨应用还要考虑 exported 和组件权限,后台启动也可能受限制。显式只意味着明确指定目标,并没有跳过系统的合法性和运行条件检查。
PackageManager 查询不到,但设备明明装了应用,为什么?
我会先查当前用户、应用启用状态、查询 flags 和包可见性。现代 Android 会限制普通应用能查询到的其他应用范围,所以查询结果不是设备完整安装清单。根据业务需要声明适当的可见范围,再用目标系统规则验证;不能直接把“查不到”当作“未安装”。
易混淆点
PMS 也常被用来缩写 PowerManagerService;后者管电源相关状态,两者无关。包管理框架不是所有运行时权限与访问规则的唯一执行者。
参考资料
内容来源
- Android 技术札记 · 原条目
pms-basics