深入解析 Android PMS —— APK 安装与解析全流程

文章目录

  • 前言
  • 1. PMS 的初始化
    • 1.1 SystemServer 启动 PMS
    • 1.2 PMS 的入口方法 main
    • 1.3 PMS 构造函数
    • 1.4 扫描 APK 文件
    • 1.5 权限初始化
    • 1.6 提供对外服务
  • 2. APK 安装机制
    • 2.1. 安装请求的触发
    • 2.2 APK 文件解析与验证
    • 2.3 签名校验
    • 2.4 权限管理
      • 2.4.1 权限声明
      • 2.4.2 权限校验与分配
    • 2.5 持久化存储
    • 2.6 广播通知
  • 3. APK 解析流程
    • 3.1 APK 文件读取
    • 3.2 APK 校验
      • 3.2.1 签名校验
      • 3.2.2 APK 格式校验
      • 3.2.3 权限检查
      • 3.2.4 其他格式校验
    • 3.3 安装信息持久化
  • 4. Intent 和组件管理
    • 4.1 Intent 的作用
    • 4.2 组件的管理
      • 源码解析
          • resolveIntent() 方法
          • queryIntentActivities() 方法
  • 5. 卸载流程
    • 5.1 卸载请求的触发
    • 5.2 PackageManagerService 接收到卸载请求
  • 5.3 停用应用
    • 5.4 删除应用数据
    • 5.5 更新系统数据库
    • 5.6 广播通知
    • 5.7 删除 APK 文件
    • 5.8 更新 UI
  • 6. 持久化机制
    • 6.1 持久化数据存储位置
    • 6.2 数据存储格式
    • 6.3 持久化流程
      • 6.3.1 应用安装时持久化
      • 6.3.2 应用卸载时持久化
      • 6.3.3 应用更新时持久化
    • 主要类
  • 总结


前言

在 Android 系统中,PackageManagerService(简称 PMS)是负责管理应用程序的核心服务。无论是应用安装、卸载,还是权限分配,PMS 都扮演着至关重要的角色。
本篇文章将带你深入探讨 PMS 的幕后机制,特别是 APK 安装与解析的详细流程。


1. PMS 的初始化

步骤 完成任务 影响范围
启动 PMS 服务 注册 PMS 到 ServiceManager,成为系统管理的核心服务。 提供应用管理能力,供系统其他组件调用。
初始化组件 构建数据结构、组件解析器,启动后台线程。 提供运行时支持,准备后续任务。
加载持久化数据 恢复设备重启前的已安装应用信息。 确保已安装应用在系统重启后仍被识别和管理。
扫描并解析 APK 扫描系统和用户目录,解析 APK 元数据,并注册到内存。 让系统能够识别和管理设备上的所有 APK。
初始化权限系统 加载默认权限配置文件,为系统应用分配权限。 保障系统安全,防止权限滥用。
提供对外接口 通过 API 提供安装、卸载、查询等功能,供系统和开发者调用。 提供应用安装和运行管理能力。

1.1 SystemServer 启动 PMS

源码路径:
frameworks/base/services/java/com/android/server/SystemServer.java

PMS 是 Android 启动服务的关键部分,在 startOtherServices() 方法中初始化:

private void startOtherServices() {
   
   
    PackageManagerService pms = PackageManagerService.main(mSystemContext);
    ServiceManager.addService("package", pms);
}
  • 主要工作:
    1、调用 PackageManagerService.main() 方法,启动 PMS。
    2、注册 PMS 服务到 ServiceManager,供系统其他服务访问。

1.2 PMS 的入口方法 main

代码路径: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public static PackageManagerService main(Context context) {
   
   
    Installer installer = new Installer();
    return new PackageManagerService(context, installer, ...);
}
  • 主要工作:
    创建 Installer 实例,用于管理 APK 文件的安装和删除。
    构造 PackageManagerService 对象。

1.3 PMS 构造函数

代码路径: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

public PackageManagerService(Context context, Installer installer, ...) {
   
   
    mContext = context;
    mInstaller = installer;
    
    // 初始化数据结构
    mPackages = new ArrayMap<>();
    mComponentResolver = new ComponentResolver();

    // 创建并启动后台线程
    mBackgroundThread = BackgroundThread.get();
    mHandler = new PackageHandler(mBackgroundThread.getLooper());

    // 初始化权限管理服务
    mPermissionManager = new PermissionManagerService(context, ...);

    // 恢复持久化存储的数据
    mSettings = new Settings(...);
    mSettings.readPackageRestrictionsLPr();

    // 启动扫描逻辑
    scanPackages();
}

初始化内容:

  • 核心数据结构:
    mPackages: 存储已安装包的信息。
    mComponentResolver: 解析组件(Activity、Service 等)依赖关系。
  • 后台线程:
    创建 BackgroundThread 处理异步任务,如 APK 扫描和安装。
  • 权限管理:
    初始化 PermissionManagerService 管理动态权限和默认权限。
  • 持久化存储:
    从 packages.xml 和 packages.list 加载已安装应用的状态。
  • 启动扫描:
    调用 scanPackages(),扫描系统目录和用户目录。

1.4 扫描 APK 文件

代码路径: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

private void scanPackages() {
   
   
    scanDirLI(new File("/system/app"), ...); // 扫描系统目录
    scanDirLI(new File("/data/app"), ...);  // 扫描用户目录
}

private void scanDirLI(File dir, ...) {
   
   
    File[] files = dir.listFiles();
    for (File file : files) {
   
   
        if (file.isFile() && file.getName().endsWith(".apk")) {
   
   
            try {
   
   
                // 解析 APK
                PackageParser.Package pkg = parsePackage(file);
                // 注册包信息
                scanPackageLI(pkg, ...);
            } catch (PackageParserException e) {
   
   
                Slog.e(TAG, "Failed to parse package: " + file, e);
            }
        }
    }
}

解析逻辑:

  • 调用 PackageParser 解析 APK 的 AndroidManifest.xml。
  • 验证签名、权限、依赖等信息。
  • 将解析后的包注册到内存数据结构。

1.5 权限初始化

代码路径: frameworks/base/services/core/java/com/android/server/pm/PermissionManagerService.java

public void initializeDefaultPermissions() {
   
   
    // 加载默认权限配置
    loadDefaultPermissions();
    for (String permission : defaultPermissions) {
   
   
        grantPermission(permission);
    }
}

主要工作:

  • 加载 /etc/permissions 目录下的权限定义文件。
  • 为系统应用自动授予默认权限。

1.6 提供对外服务

代码路径: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

注册到 ServiceManager 后,PMS 提供以下对外服务:

1、获取已安装应用列表:

public List<PackageInfo> getInstalledPackages() {
   
   ...}

2、安装应用:

public void installPackage(String packageName, ...) {
   
   ...}

3、卸载应用:

public void deletePackage(String packageName, ...) {
   
   ...}

2. APK 安装

你可能感兴趣的:(Android,FrameWork,android)