PackageManagerService分析

本文详细解析了Android系统中PackageManagerService的启动流程,从Settings类的初始化开始,介绍了其负责保存与PackageManagerService相关的设置,再到SystemServer如何调用PackageManagerService的主要方法。分析了五个关键文件的作用,包括记录应用信息的packages.xml及其备份文件等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在分析PackageManagerService中main()之前,先分析Settings类.这个类用来保存和PackageManagerService相关的一些设置.先来看看Settings类的方法,代码如下

    Settings(Object lock) {
        this(Environment.getDataDirectory(), lock);
    }

    Settings(File dataDir, Object lock) {
        mLock = lock;

        mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);

        mSystemDir = new File(dataDir, "system");
        mSystemDir.mkdirs();
        FileUtils.setPermissions(mSystemDir.toString(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG
                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                -1, -1);
        mSettingsFilename = new File(mSystemDir, "packages.xml");
        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
        mPackageListFilename = new File(mSystemDir, "packages.list");
        FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);

        // Deprecated: Needed for migration
        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
    }
以上的方法主要作用是创建了5个位于data/system/目录下的File对象.

1)packages.xml: 记录系统中所有安装的应用信息,包括基本信息,签名和权限.

2)packagers-backup.xml:是packages.xml文件的备份.

3)packagers-stopped.xml:记录系统中被强制停止运行的应用信息.系统在强制停止某个应用时,会将应用的信息记录到改文件中.

4)packagers-stopped-backup.xml:是packagers-stopped.xml备份.

5)packages.list:保存普通应用的数据目录和uid等信息.


分析完Settings.java的一些基本信息,我们来分析下PackageManagerService.java的初始化基本过程

Step 1 :

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中

    /**
     * Starts a miscellaneous grab bag of stuff that has yet to be refactored
     * and organized.
     */
private void startOtherServices() {
       ....
        try {
            mPackageManagerService.performBootDexOpt();
        } catch (Throwable e) {
            reportWtf("performing boot dexopt", e);
        }
     ...
     try {
            mPackageManagerService.systemReady();
        } catch (Throwable e) {
            reportWtf("making Package Manager Service ready", e);
        }
    }

 private void startBootstrapServices() {
        ....
        // Start the package manager.
        Slog.i(TAG, "Package Manager");
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();

       ...
        startSensorService();
    }

通过以上代码可以看出,SystemServer对PackagerManagerService的初始化主要通过上面的代码来完成的,接下来我们来分析下PackagerManagerService的main初始化过程.

Step 2:

这个文件定义在frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java中

    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        PackageManagerService m;
        if (FeatureConfig.INTEL_FEATURE_PARALLEL_SCAN) {
            int taskNum = SystemProperties.getInt("persist.pms.tasknum",
                    Runtime.getRuntime().availableProcessors()*2);
            m = new PackageManagerService(context, installer,
                    factoryTest, onlyCore, taskNum);
        } else {
            m = new PackageManagerService(context, installer,
                    factoryTest, onlyCore);
        }
        ServiceManager.addService("package", m);
        return m;
    }

通过以上代码看出,main的方法比较简单,主要是创建了PackageManagerService对象并在ServiceManager注册.
### 解决 PackageManagerService 死锁问题 #### 了解 PackageManagerService 的工作原理 PackageManagerService (PMS) 是 Android 系统中的核心组件之一,负责管理和维护应用程序包的信息。当 PMS 出现死锁情况时,通常是因为多个线程试图获取相同的资源而互相等待造成的。 为了有效解决这个问题,首先要理解 PMS 如何与其他系统服务交互以及其内部的工作机制[^1]。 #### 使用 Watchdog 进行监控 Android 系统内置了一个名为 Watchdog 的单例线程,在 System Server 初始化阶段即被创建并运行。Watchdog 能够检测到包括 PMS 在内的关键系统服务是否存在无响应的情况,并触发相应的恢复操作。因此,利用好 Watchdog 可以为诊断和预防 PMS 死锁提供帮助[^3]。 #### 分析日志信息 遇到 PMS 死锁问题时,应该收集尽可能详细的日志记录,特别是 ANR(Application Not Responding)报告。这些日志可以帮助识别哪些线程处于阻塞状态及其持有的锁对象。通过分析堆栈跟踪和其他上下文线索,可以更精准地定位引发死锁的具体原因。 #### 修改代码逻辑避免竞争条件 一旦确认了潜在的死锁源,则需审查涉及的相关代码部分,寻找可能存在的竞态条件或不合理的同步策略。对于复杂的并发场景,考虑采用更加高效且安全的方式处理共享资源访问,比如减少不必要的加锁范围、优化锁粒度或是引入读写分离机制等措施来降低发生死锁的风险[^2]。 #### 测试验证修复效果 完成上述调整之后,务必进行全面测试以确保新版本不会再次陷入相同类型的死锁陷阱之中。这不仅限于单元测试层面,还应涵盖集成测试乃至真实设备上的压力测试等多个维度来进行充分检验。 ```java // 示例:简化后的伪代码展示如何改进同步方式 synchronized void methodA() { // 原有方法体... } void improvedMethodA(Object lockObj) { synchronized(lockObj){ // 改进后的方法体, 尽量缩小锁定区域 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值