PackageManagerService(1)扫描前的准备

本文深入剖析了PKMS(PackageManagerService)的源码,详细解读了其在Android系统中的初始化流程,包括变量初始化、权限管理、配置文件加载、共享进程及库信息保存等关键步骤。

PKMS( PackageManagerService简称 )是一个系统服务,它的主要功能是解析APK并保存数据。由于在工作遇到过一些麻烦,最终的原因是由于对PKMS理解不够导致的,因此我决心把PKMS的源码重新并整理一次,以加深理解。

由于PKMS的代码量非常大,为了缓存阅读文章的疲劳,我将分三步讲解,如下

  1. 扫描APK前的准备工作。
  2. 扫描目录并解析APK
  3. 保存解析数据到文件。

扫描前准备工作

初始化

本文只分析第一阶段的工作,扫描前的准备工作。由于代码量非常大,因此分段来分析

	// frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
    
    public PackageManagerService(Context context, Installer installer,
                                 boolean factoryTest, boolean onlyCore) {
   
   
		// ...

        mContext = context;
		// factory test mode下为true,正常模式启动下,为false
        mFactoryTest = factoryTest;
        // 设备正在加密或者已经加密状态下,这个值为true,正常模式启动下,值为false
        mOnlyCore = onlyCore;
        mMetrics = new DisplayMetrics();
        mInstaller = installer;
		
        // 1. 初始化
        synchronized (mInstallLock) {
   
   
            synchronized (mPackages) {
   
   
                // Expose private service for system components to use.
                // 从注释看,这里是暴露私有接口供系统组件使用
                LocalServices.addService(
                        PackageManagerInternal.class, new PackageManagerInternalImpl());

                sUserManager = new UserManagerService(context, this,
                        new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);

                // ComponentResolver 用于在匹配四大组件时,解析数据
                mComponentResolver = new ComponentResolver(sUserManager,
                        LocalServices.getService(PackageManagerInternal.class),
                        mPackages);

                // 用于管理权限服务端
                mPermissionManager = PermissionManagerService.create(context,
                        mPackages /*externalLock*/);
                // DefaultPermissionGrantPolicy类型
                mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();

                mSettings = new Settings(Environment.getDataDirectory(),
                        mPermissionManager.getPermissionSettings(), mPackages);
            }
        }
        
        // ...
	}        

这里初始化了很多变量,这些变量到底有什么用,一时间还真难总结出来。然而,随着我们分析的逐步深入,自然就会明白这些变量的作用了。

这里我们主要关心 mPermissionManager 变量的初始化,它调用的是PermissionManagerService#create() 方法

	// frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
    
    public static PermissionManagerServiceInternal create(Context context,
            @NonNull Object externalLock) {
   
   
        final PermissionManagerServiceInternal permMgrInt =
                LocalServices.getService(PermissionManagerServiceInternal.class);
        if (permMgrInt != null) {
   
   
            return permMgrInt;
        }
        new PermissionManagerService(context, externalLock);
        // 返回值是在PermissionManagerService构造函数中保存的
        return LocalServices.getService(PermissionManagerServiceInternal.class);
    }

首次调用这个方法,会先创建 PermissionManagerService 对象,然后返回的 PermissionManagerService 内部接口的一个对象。

创建 PermissionManagerService

那么来看下 PermissionManagerService 创建时候做了什么

    PermissionManagerService(Context context,
            @NonNull Object externalLock) {
   
   
         // 1. 初始化变量
        mContext = context;
        mLock = externalLock;
        mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
        mUserManagerInt = LocalServices.getService(UserManagerInternal.class);

        // PermissionSettings用于存储权限
        mPermissionSettings = new PermissionSettings(mLock);

        // 创建后台线程和Handler
        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        Watchdog.getInstance().addThread(mHandler);

        // 一个默认的授权策略类
        mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
                context, mHandlerThread.getLooper(), this);
		
		// 2. 从SystemConfig中获取信息
        // SystemConfig是一个单例,在创建的时候会解析系统的配置文件
        SystemConfig systemConfig = SystemConfig.getInstance();
        // 保存SystemConfig解析的<assign-permission>标签的内容
        mSystemPermissions = systemConfig.getSystemPermissions()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值