PMS 全称是PackageManagerService是 Android 系统中负责应用包管理的核心系统服务运行在 SystemServer 进程中。没有它系统无法知道安装了哪些应用、每个应用有什么组件、需要什么权限。它是 AMS 启动 Activity/Service 时查询目标组件信息的数据源也是权限系统的核心支撑。一、 核心职责职责说明APK 安装/卸载/更新处理adb install、应用商店安装、系统更新等包信息解析解析 AndroidManifest.xml提取组件、权限、声明权限管理检查/授予运行时权限、签名验证组件查询提供queryIntentActivities()、resolveService()等查询签名验证验证 APK 签名一致性防止篡改共享库管理管理共享库shared libraries依赖用户隔离多用户场景下包的隔离管理二、 在 SystemServer 中的启动位置// SystemServer.startBootstrapServices()mPackageManagerServicePackageManagerService.main(mSystemContext,installer,domainVerificationService,...);PMS 属于Bootstrap 阶段启动的服务因为它被 AMS、WMS 等众多后续服务依赖。三、与 PackageManager 的关系对比PackageManagerPackageManagerService所在进程应用进程SystemServer 进程实现方式抽象类应用侧接口具体实现服务端逻辑通信方式通过 Binder 调用 PMS直接操作底层数据典型方法getPackageInfo()、getInstalledPackages()实际执行查询逻辑应用进程通过 Context.getPackageManager() 获取的是 ApplicationPackageManager它内部持有 PMS 的 Binder 代理所有调用最终跨进程到 SystemServer 的 PMS。四、 PMS 启动流程详解4.1 构造阶段PackageManagerService()// PackageManagerService.javapublicPackageManagerService(Injectorinjector,booleanonlyCore,booleanfactoryTest){// 1. 创建 HandlerThread后台扫描线程mHandlerThreadnewServiceThread(TAG,Process.THREAD_PRIORITY_BACKGROUND,true);mHandlerThread.start();mHandlernewPackageHandler(mHandlerThread.getLooper());// 2. 创建并加载 Settings持久化数据mSettingsnewSettings(...);mSettings.readLPw();// 读取 /data/system/packages.xml// 3. 初始化 Installer底层安装接口mInstallernewInstaller();// 4. 创建 DexOpt 优化器mPackageDexOptimizernewPackageDexOptimizer(this);// 5. 创建 PackageParserAPK 解析器mPackageParsernewPackageParser();// ... 大量初始化 ...}4.2 扫描阶段scanDirTracedLI()// 扫描系统目录按优先级scanDirTracedLI(newFile(/system/framework),...);// 框架scanDirTracedLI(newFile(/system/priv-app),...);// 系统特权应用scanDirTracedLI(newFile(/system/app),...);// 系统应用scanDirTracedLI(newFile(/vendor/app),...);// 厂商应用scanDirTracedLI(newFile(/product/app),...);// 产品应用scanDirTracedLI(newFile(/data/app),...);// 用户应用扫描顺序决定覆盖优先级后扫描的目录可以覆盖先扫描目录中的同名包版本更高时。五、APK 解析机制PackageParser5.1 解析流程5.2 解析结果存储// PackageParser.Package 结构publicfinalclassPackage{publicStringpackageName;// 包名publicStringmSharedUserId;// 共享用户IDpublicApplicationInfoapplicationInfo;publicfinalArrayListActivityactivitiesnewArrayList();publicfinalArrayListActivityreceiversnewArrayList();publicfinalArrayListServiceservicesnewArrayList();publicfinalArrayListProviderprovidersnewArrayList();publicfinalArrayListPermissionpermissionsnewArrayList();publicfinalArrayListInstrumentationinstrumentationnewArrayList();// ...}六、Settings 与持久化存储6.1 持久化文件文件路径作用/data/system/packages.xml所有已安装包的信息、权限授予状态/data/system/packages-backup.xmlpackages.xml 备份/data/system/packages.list包名到 UID/GID 的映射列表/data/system/users/每个用户的包状态是否启用、是否停止6.2 packages.xml 结构?xml version1.0 encodingutf-8?packages!-- 包信息 --packagenamecom.example.appcodePath/data/app/com.example.app-1nativeLibraryPath/data/app/...primaryCpuAbiarm64-v8apublicFlags...privateFlags...ft...it...ut...version100userId10123!-- 签名信息 --sigscount1certindex1//sigs!-- 权限授予 --permsitemnameandroid.permission.CAMERAgrantedtrueflags0/itemnameandroid.permission.INTERNETgrantedtrueflags0//perms!-- 组件状态 --proper-signing-keysetidentifier1//package!-- 共享用户 --shared-usernameandroid.uid.systemuserId1000sigscount1certindex1//sigs/shared-user/packages6.3 Settings 类核心结构// Settings.javafinalclassSettings{// 所有已安装包privatefinalArrayMapString,PackageSettingmPackagesnewArrayMap();// 共享用户设置privatefinalArrayMapString,SharedUserSettingmSharedUsersnewArrayMap();// 签名到索引的映射去重存储privatefinalArrayMapSignature,IntegermSignaturesnewArrayMap();// 权限基线权限定义privatefinalArrayMapString,BasePermissionmPermissionsnewArrayMap();// 写入持久化voidwriteLPr(){...}// 写入 packages.xmlvoidreadLPw(){...}// 读取 packages.xml}七、权限管理机制7.1 权限类型类型说明示例Normal安装时自动授予无需用户确认INTERNET、ACCESS_NETWORK_STATEDangerous运行时动态申请需用户授权CAMERA、LOCATION、READ_CONTACTSSignature仅与定义者同签名的应用可获取BIND_WALLPAPERPrivileged仅系统特权应用priv-app可获取WRITE_SECURE_SETTINGSInternal仅系统应用可获取INTERACT_ACROSS_USERS7.2 运行时权限申请流程7.3 权限授予源码// PackageManagerService.javaOverridepublicvoidgrantRuntimePermission(StringpackageName,StringpermissionName,intuserId){synchronized(mPackages){// 1. 获取包设置PackageParser.PackagepkgmPackages.get(packageName);BasePermissionbpmSettings.mPermissions.get(permissionName);// 2. 检查权限是否可授予if(!bp.isRuntime()){thrownewSecurityException(Not a runtime permission);}// 3. 获取权限设置PermissionsStatepermissionsStatepkg.mExtras.permissionsState;// 4. 授予权限intresultpermissionsState.grantRuntimePermission(bp,userId);// 5. 持久化mSettings.writeLPr();// 6. 发送广播通知mHandler.post(()-{sendPackageChangedBroadcast(packageName,...);});}}八、签名验证机制8.1 签名验证时机时机验证内容安装时验证 APK 签名完整性更新时验证新旧 APK 签名一致共享 UID验证同 UID 的所有包签名一致权限声明验证权限定义者的签名8.2 签名存储优化PMS 使用签名索引去重来节省内存// 多个包可能使用相同签名如同一开发者// PMS 只存储一份签名对象通过索引引用// 首次遇到签名mSignatures.put(signature,index1);// 存储实际签名// 后续相同签名// 只存储索引引用不重复存储签名对象九、DexOpt 与 ART 优化9.1 优化类型类型说明存储位置dexoptDalvik 时代的优化odex/data/dalvik-cache/dex2oatART 时代的 AOT 编译oat/data/app/.../oat/vdex验证后的 dexAndroid 8/data/app/.../oat/cdex压缩 dexAndroid 10/data/app/.../oat/9.2 优化触发时机// PackageDexOptimizer.javaintperformDexOpt(PackageParser.Packagepkg,...){// 1. 检查是否需要优化首次安装、系统更新、ART 升级if(!needsDexOpt(pkg))returnDEX_OPT_SKIPPED;// 2. 调用 dex2oat 进行 AOT 编译// dex2oat --dex-fileapp.apk --oat-fileapp.odex// 3. 更新优化状态pkg.setDexOptPerformed(...);returnDEX_OPT_PERFORMED;}十、多用户支持10.1 用户隔离机制// UserManagerService PMS 协同// 每个用户独立的数据目录/data/user/0/com.example.app/// 用户0主用户/data/user/10/com.example.app/// 用户10工作资料// PMS 为每个用户维护独立的包状态classPackageSetting{// 每个用户的包状态int[]enabledState;// 是否启用int[]stoppedState;// 是否强制停止boolean[]hidden;// 是否隐藏}10.2 应用克隆/双开部分 OEM 系统利用多用户机制实现应用双开创建独立用户空间如 User 999在该用户空间安装相同 APK两个用户空间的包数据完全隔离十一、PackageInstaller 与 Session 安装11.1 现代安装流程Android 711.2 Session 安装的优势传统安装Session 安装一次性写入完整 APK支持流式写入分片传输安装失败需清理残留原子提交失败自动回滚不支持多 APKsplit原生支持 base split APK无进度反馈支持安装进度回调十二、PMS 与 AMS 的交互12.1 组件启动时的查询12.2 应用进程创建时的包信息传递// AMS 创建进程时通过 PMS 获取包信息ApplicationInfoappInfoPMS.getApplicationInfo(packageName,0,userId);// 将 ApplicationInfo 传递给 Zygote fork 出的新进程ProcessRecordappnewProcessRecord(...,appInfo,...);十三、PMS 的性能优化13.1 启动优化优化手段说明并行扫描多线程并行扫描不同目录缓存机制解析结果缓存避免重复解析增量更新仅扫描变更的 APK后台 dexopt首次启动后后台执行 AOT 编译13.2 内存优化// 使用 ArrayMap 替代 HashMapAndroid 专用优化privatefinalArrayMapString,PackageParser.PackagemPackages;// 签名去重存储privatefinalArrayMapSignature,IntegermSignatures;// 组件信息延迟加载// 非系统应用的部分组件信息按需加载十四、关键问题排查14.1 常见日志# 查看 PMS 相关日志adb logcat-sPackageManager:D PackageManagerService:D# 查看 packages.xmladb shellcat/data/system/packages.xml|grepyour.package.name# 查看应用权限adb shell dumpsys package your.package.name14.2 常见问题问题原因排查方向安装失败INSTALL_FAILED_UPDATE_INCOMPATIBLE签名不一致检查 debug/release 签名安装失败INSTALL_FAILED_SHARED_USER_INCOMPATIBLEsharedUserId 签名不匹配检查 AndroidManifest权限未生效权限组变更或用户拒绝检查packages.xml权限状态组件找不到组件未声明或 exportedfalse检查AndroidManifest.xml十五、总结