【笔记】Installd , Installer 分析

                                                                          1.  Installd

1.installd  在SystemServer.java  中创建,Android APK的安装和卸载主要是由Installer和Installd完成的

2.PackageManageService这么大的组件了,为什么还需要intalld这个守护进程?这是因为权限的问题,PackageManagerService只有system权限。installd却是在init.rc 中启动的,具有root权限

3.frameworks/native/cmds/installd/installd.cpp
  frameworks/base/services/core/java/com/android/server/pm/Installer.java

4.installd 会创建/data/app/ , /data/app-private/ , /data/app-lib/ , /mnt/asec/ , /data/media , /mnt/expand , /system/app , /system/app-lib , /vendor/app/  等目录。

5.installd 也创建了  /data/media/0  目录。

6.PKMS <----> Installer <----> socket<---->Instal

<think>我们被要求分析PackageManagerService.java中应用安装和卸载的流程。根据提供的引用,特别是引用[3]和引用[4],我们可以大致了解PMS在应用安装和卸载过程中的核心作用。 安装流程: 1. 解析AndroidManifest.xml:获取应用的基本信息,如包名、版本、组件(activity、service等)声明、权限等。 2. 验证和准备安装:检查安装条件(如签名、权限、存储空间等),确定安装位置(内部存储或SD卡)。 3. 复制APK文件到目标目录:通常是将APK复制到/data/app目录下。 4. 创建应用数据目录:在/data/data/下创建以包名命名的目录,用于存放应用的数据。 5. 更新系统状态:将新安装的应用信息添加到PMS的内部数据结构中,更新权限信息,发送广播通知系统应用状态变化。 卸载流程: 1. 删除APK文件:从/data/app目录中移除APK文件。 2. 删除应用数据目录:包括/data/data/包名下的数据目录和可能存在的SD卡上的数据。 3. 更新系统状态:从PMS的内部数据结构中移除该应用的信息,更新权限信息,发送广播通知系统。 根据引用[4],卸载过程还需要注意多用户环境、共享库依赖以及系统应用的特殊处理。 现在,我们结合引用[3]中提到的源码位置,进一步分析安装和卸载流程。 安装流程详细步骤(参考源码): - 入口:PackageManagerService的installPackage方法(可能通过PackageInstallerService触发)。 - 步骤: 1. 解析包(parsePackage):使用PackageParser解析APK文件,生成Package对象。 2. 验证安装包(verifySignatures等):检查签名,确保安全。 3. 执行安装(installPackageLI):这是安装的核心方法,其中LI表示需要持有安装锁(mInstallLock)进行。 - 将APK文件复制到目标目录(如/data/app/包名-1/base.apk)。 - 创建应用数据目录(通过InstallerConnection调用installd创建目录并设置权限)。 - 将解析得到的Package信息添加到PMS的mPackages等数据结构中。 - 更新权限(updatePermissionsLI)和设置(如默认的权限授予)。 - 发送广播(ACTION_PACKAGE_ADDED)通知系统新包已安装。 卸载流程详细步骤: - 入口:PackageManagerService的deletePackage方法。 - 步骤: 1. 删除包(deletePackageLI):需要持有安装锁(mInstallLock)。 - 删除APK文件(从/data/app目录)。 - 通过InstallerConnection调用installd删除应用的数据目录(/data/data/包名)。 - 从PMS的mPackages等数据结构中移除该包的信息。 - 更新权限(updatePermissionsLI)。 - 发送广播(ACTION_PACKAGE_REMOVED)通知系统包已被移除。 注意:卸载系统应用时,如果系统应用有更新,则卸载更新会回退到初始版本;如果是预装应用,则可能无法卸载(只能禁用)。 根据引用[3]和引用[4],我们还可以了解到PMS通过Binder与installd(一个本地守护进程)交互来执行文件操作(如复制、删除、设置权限等)。installd负责处理应用目录的创建和删除,因为它需要以root权限运行。 在分析源码时,可以重点关注以下方法: - installPackageLI:安装的核心逻辑。 - deletePackageLI:卸载的核心逻辑。 - scanPackageTracedLI:扫描安装包,解析包信息。 - deleteDir:删除目录(通过installd)。 另外,引用[3]提到,在安装过程中,PMS会检查白名单(如果实现了白名单功能)。这通常是在安装前进行的权限检查。 由于源码较长,这里不贴出完整代码,但我们可以描述关键步骤。 安装流程(详细): 1. 通过Binder调用到PMS的installPackage方法(可能来自PackageInstaller应用)。 2. 进行权限检查(调用者必须具有INSTALL_PACKAGES权限)。 3. 创建InstallParams(处理安装参数),并将其加入处理队列。 4. 在Handler处理中,调用processInstallRequestAsync开始异步处理。 5. 在安装过程中,会调用installPackageTracedLI方法,该方法内部调用installPackageLI。 6. 在installPackageLI中: - 创建安装目录(如果需要)。 - 将APK文件复制到/data/app目录(通常使用AtomicFile确保原子性)。 - 解析APK(PackageParser.parsePackage)。 - 验证签名。 - 如果之前有安装,则进行升级操作(替换APK,保留数据)。 - 为新安装的应用分配UID(如果未指定)。 - 调用scanPackageNewLI扫描新安装的包,将其添加到PMS的mPackages中。 - 更新Settings(将新包的信息写入packages.xml和packages.list)。 - 为新应用创建数据目录(通过mInstaller.createAppData创建)。 - 发送广播。 卸载流程(详细): 1. 通过Binder调用PMS的deletePackage方法。 2. 进行权限检查(调用者必须具有DELETE_PACKAGES权限)。 3. 创建DeletePackageArgs,并调用deletePackageVersioned方法。 4. 最终调用deletePackageLI方法: - 检查包是否存在,以及是否允许卸载(如系统应用不可卸载,但可以卸载更新)。 - 删除APK文件(移除/data/app下的目录)。 - 删除数据目录(通过mInstaller.destroyAppData递归删除数据目录)。 - 从PMS的mPackages等结构中移除包信息。 - 更新Settings(从packages.xml和packages.list中移除)。 - 发送广播。 以上是应用安装和卸载的主要流程。由于Android版本不同,具体实现可能有所差异,但核心步骤基本一致。 相关问题: 1. 在应用安装过程中,PMS是如何处理共享库依赖的? 2. 在卸载系统应用更新时,PMS是如何回退到初始版本的? 3. PMS在安装过程中如何确保多个用户之间的应用安装隔离?</think>### PackageManagerService 应用安装与卸载流程分析 #### **一、应用安装流程** 1. **入口与权限校验** 安装请求通过 `PackageManagerService.installPackage()` 入口触发[^3]。首先校验调用者权限(`INSTALL_PACKAGES`),并验证 APK 签名和包名合法性。 2. **APK 文件处理** - 复制 APK 到目标目录:`/data/app/<包名>-<随机后缀>` - 调用 `Installer` 服务(通过 `installd` 守护进程)创建应用数据目录:`/data/data/<包名>`[^4]。 3. **解析与注册** - 使用 `PackageParser` 解析 APK 的 `AndroidManifest.xml`,生成 `Package` 对象[^3]。 - 更新 PMS 内部数据结构: ```java mPackages.put(packageName, pkg); // 添加到包列表 mSettings.writeLPr(); // 写入packages.xml ``` - 注册四大组件(Activity/Service 等)到 `ActivityTaskManagerService`[^3]。 4. **资源优化与权限分配** - 调用 `performDexOpt()` 执行 Dex 优化(生成 ODEX 文件)。 - 分配应用 UID 并授予声明权限,更新 `packages.list` 文件[^4]。 5. **广播通知** 发送 `ACTION_PACKAGE_ADDED` 广播,通知系统应用安装完成[^4]。 --- #### **二、应用卸载流程** 1. **入口与校验** 卸载请求通过 `PackageManagerService.deletePackage()` 触发,校验 `DELETE_PACKAGES` 权限[^4]。 2. **资源清理** - 删除 APK 文件:`/data/app/<包名>-<随机后缀>` - 通过 `Installer.destroyAppData()` 删除数据目录: ```java mInstaller.destroyAppData(packageName, userId, flags); // 清理/data/data/<包名> ``` - 若为 SD 卡安装,同步删除外部存储数据[^4]。 3. **状态更新** - 从 PMS 内部结构移除包信息: ```java mPackages.remove(packageName); mSettings.removePackageLPw(packageName); // 更新packages.xml ``` - 撤销应用权限并回收 UID[^3]。 4. **多用户与依赖处理** - **多用户环境**:遍历所有用户删除应用数据(`/data/user/<userId>/<包名>`)。 - **共享库依赖**:检查是否有其他应用依赖当前包的共享库,若有则强制停止依赖应用[^4]。 5. **系统应用特殊处理** - 卸载系统应用更新时,回退到初始版本(`/system/app` 下的原始 APK)。 - 发送 `ACTION_PACKAGE_REMOVED` 广播[^4]。 --- #### **三、关键源码位置** 1. **安装核心逻辑** - 入口:`PackageManagerService.installPackage()` - APK 复制:`FileUtils.copyFile()` - 包解析:`PackageParser.parsePackage()`[^3] - 数据目录创建:`Installer.createAppData()` 2. **卸载核心逻辑** - 入口:`PackageManagerService.deletePackageVersioned()` - 资源删除:`Installer.destroyAppData()` - 状态更新:`Settings.removePackageLPw()`[^4] 3. **跨进程通信** PMS 通过 Binder 与 `installd` 交互,文件操作由 `InstallerConnection` 实现[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值