Android源码分析-PackageManagerService(PMS)源码分析(一)PMS的初始化以及PackageManager的使用

Android 11.0 PackageManagerService(一)工作原理和启动流程 1. 概述 PackageManagerService是Android系统核心服务之一,也是Android中最常用的服务之一。它主要负责的工作如下: 1. 解析AndroidManifest.xml文件,解析清单文件中的所有节点信息。 2. 扫描.apk文件,安装系统应用,本地应用等。 3. 管理本地应用,主要有:安装、卸载、应用信息查询等。 2. 核心源码 /frameworks/base/core/java/android/app/ApplicationP... 阅读详情

一,PackageManagerService(PMS)服务简介:

PackageManagerService(简称PMS),顾名思义,用于进行Android包的管理。利用PackageManagerService服务,可以查询应用程序等信息,以及安装包(package)信息,以及该应用activity,service,权限等组件的信息。PackageManagerService是Android系统中的一个系统服务。

Android系统中,提供了PackageManager类来对外(应用程序)提供API接口,对内(Android系统)与PMS进行IPC通信,最终通过PMS来实现真正的功能。

Android系统对PackageManager定义成了抽象类,而其真正的具体功能是在ApplicationPackageManager类中(ApplicationPackageManager是PackageManager的派生类)实现的。

二,PackageManagerService架构图:

PackageManagerService架构图(相关类图):

 

三,PackageManager的常用数据成员和常用方法:

列出了3个常用的方法:

public abstract PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException; //获取包的信息

public abstract PermissionInfo getPermissionInfo(String name, int flags)
        throws NameNotFoundException; //获取权限信息
public abstract ActivityInfo getActivityInfo(ComponentName component,
        int flags) throws NameNotFoundException; //获取activity信息

 更多的方法,如下图:

四,ApplicationPackageManager的常用数据成员和常用方法:

ApplicationPackageManager继承自PackageManager,PackageManager的很多abstract方法都是ApplicationPackageManager来实现的。

常用方法,如下图:

五,PackageManagerService的初始化代码分析:

5.1 PMS的初始化:

和其它Framework组件一样,PMS是在SystemServer中进行的初始化,代码如下:

SystemServer.java中,PackageManagerService的初始化:

pm = PackageManagerService.main(context,
                    factoryTest != SystemServer.FACTORY_TEST_OFF,
                    onlyCore);
            boolean firstBoot = false;
            try {
                firstBoot = pm.isFirstBoot();
            } catch (RemoteException e) {
            }

。。。。。。


try {
            pm.performBootDexOpt();
        } catch (Throwable e) {
            reportWtf("performing boot dexopt", e);
        }

。。。。。。

try {
            pm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Package Manager Service ready", e);
        }

在PackageManagerService.java中, 有:

public static final IPackageManager main(Context context, boolean factoryTest,
            boolean onlyCore) {
        PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }

说明:

返回的是IPackageManager类型,其真正的实例其实是:

PackageManagerService

将其加入ServerManager中,以便进行管理。

5.2 PackageManagerService的构造函数分析:

5.2.1 创建Installer实例, 获取pi屏幕大小:

        //创建Installer实例
        mInstaller = new Installer();

        //屏幕大小相关
        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        Display d = wm.getDefaultDisplay();
        d.getMetrics(mMetrics);

5.2.2  获取app安装相关目录:

            //获取app安装相关目录
            File dataDir = Environment.getDataDirectory();
            mAppDataDir = new File(dataDir, "data");
            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
            mUserAppDataDir = new File(dataDir, "user");

            //2. app安装目录: “/data/data/app-private”目录
            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");

 5.2.3  读取权限:

            readPermissions();

  5.2.4  获取framework目录和虚拟机缓存目录:

            //framework目录
            mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
            //虚拟机缓存目录
            mDalvikCacheDir = new File(dataDir, "dalvik-cache");

  5.2.5  加载框架层资源:framework-res和核心包:

            libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
            
            String[] frameworkFiles = mFrameworkDir.list();
            if (frameworkFiles != null) {
                for (int i=0; i<frameworkFiles.length; i++) {
                    File libPath = new File(mFrameworkDir, frameworkFiles[i]);
                    String path = libPath.getPath();
                    // Skip the file if we alrady did it.
                    if (libFiles.contains(path)) {
                        continue;
                    }
                    // Skip the file if it is not a type we want to dexopt.
                    if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
                        continue;
                    }
                    try {
                        if (dalvik.system.DexFile.isDexOptNeeded(path)) {
                            mInstaller.dexopt(path, Process.SYSTEM_UID, true);
                            didDexOpt = true;
                        }
                    } catch (FileNotFoundException e) {
                        Slog.w(TAG, "Jar not found: " + path);
                    } catch (IOException e) {
                        Slog.w(TAG, "Exception reading jar: " + path, e);
                    }
                }
            }

  5.2.6  获取系统app,wendor app的包信息: 

            // Collect all system packages.
            mSystemAppDir = new File(Environment.getRootDirectory(), "app");
            mSystemInstallObserver = new AppDirObserver(
                mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
            mSystemInstallObserver.startWatching();
            scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

            // Collect all vendor packages.
            mVendorAppDir = new File("/vendor/app");
            mVendorInstallObserver = new AppDirObserver(
                mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
            mVendorInstallObserver.startWatching();
            scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

5.2.7 非核心app的扫描:

            if (!mOnlyCore) {
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                mAppInstallObserver = new AppDirObserver(
                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
                mAppInstallObserver.startWatching();
                //13.扫描安装目录,最重要的步骤
                scanDirLI(mAppInstallDir, 0, scanMode, 0);
    
                mDrmAppInstallObserver = new AppDirObserver(
                    mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
                mDrmAppInstallObserver.startWatching();

                //13.扫描安装目录,最重要的步骤
                scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
                        scanMode, 0);

                ......
                }
            } 

5.2.8 更新权限: 

            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
                    | (regrantPermissions
                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
                            : 0));

 其中,最主要是scanDirLI方法,即扫描目录下的apk文件。下面主要分析这个方法(5.3)。

5.3 scanDirLI方法代码分析:

(1)scanDirLI的定义:

private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
...
//扫描dir目录下的文件,如果是apk文件,就继续执行“scanPackageLI”方法。
PackageParser.Package pkg = scanPackageLI(file,
        flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);

}

(2)scanPackageLI(重点):

private PackageParser.Package scanPackageLI(File scanFile,
            int parseFlags, int scanMode, long currentTime) {
        mLastScanError = PackageManager.INSTALL_SUCCEEDED;
        String scanPath = scanFile.getPath();
        parseFlags |= mDefParseFlags;

        PackageParser pp = new PackageParser(scanPath);

......
//
//1.创建参数
createInstallArgs


//2.身份认证
collectCertificatesLI

//3.调用另外一个重载函数
scanPackageLI

(3)主要分析scanPackageLI这个重载函数:

//初始化source和资源文件目录
File destCodeFile = new File(pkg.applicationInfo.sourceDir);
File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);

......

//签名校验
verifySignaturesLP(pkgSetting, pkg)

//安装apk
mInstaller.install(pkgName, pkg.applicationInfo.uid,
                        pkg.applicationInfo.uid);

//创建用户目录
sUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);

//native 目录的处理

//providers的处理

//servuce的处理

//receivers的处理

//permissions(权限)的处理

六,总结:

PMS中将各个app进行解析,并且保存在内存中,即PMS类的数据成员,典型的有:

PackageManagerService.java的数据成员:

final File mAppDataDir; //应用数据目录
final File mFrameworkDir; //framework目录
final File mSystemAppDir; //系统目录
final File mVendorAppDir; //vendor目录
final File mAppInstallDir; //应用安装目录
final File mDalvikCacheDir;//虚拟机缓存目录

final ActivityIntentResolver mActivities =
        new ActivityIntentResolver(); //有效activity
final ActivityIntentResolver mReceivers =
        new ActivityIntentResolver(); //有效receiver
final ServiceIntentResolver mServices = new ServiceIntentResolver();//有效service

final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
        new HashMap<ComponentName, PackageParser.Provider>();//有效ProvidersBy

当用户想查询apk的某些信息时(例如,查询包信息),就可以通过PMS查询到这些信息了。


Android PMS(PackageManagerService) 原理 为什么要有 PMS 手机里面的 apk 都会在 data/app 目录下,知道这个 apk 路径很简单,难的地方在于怎么管理 apk 里面的信息,例如怎么提供给 AMS 需要的 Activity 信息等。所以就需要 PMS 提前将 apk 的信息缓存起来。 PMS 缓存信息是在手机开机启动这段时间处理解析的,所以这也是为什么手机开启启动比较慢的原因之一。 PMS 分析 apk 压缩文件 当手机开机时,PMS 会扫描 data/app/package/base.apk,还有 system/app/packag 阅读详情

相关推荐

Android FrameWork——PackageManager框架,整理几个重要的Android知识

大部分情况我们是在Activity中使用getPackageManager方法获取一个ApplicationPackageManager的对象,ApplicationPackageManager实际上是包装了一个IPackageManager.Stub.Proxy的对象由IPackageManager.Stub.Proxy代理执行PackageManager相关操作,IPackageManager.Stub.Proxy实际代理的是PackageManagerService,

2401_87361641的博客 1263

Android PackageManager详解

Android系统为我们提供了很多服务管理的类,包括ActivityManager、PowerManager(电源管理)、AudioManager(音频管理)等。除此之外,还提供了一个PackageManger管理类,它的主要职责是管理应用程序包。 通过PackageManager,我们就可以获取应用程序信息。   提到PackageManager,就得提一下AndroidManifest.XML文件了。AndroidManifest.xml是Android应用程序中最重要的文件之一。它是Android.

看美丽风晴 9905

Android从上帝视角来看PackageManagerService

这是包管理系列的最后一篇文章,本文的标题是**从上帝视角来看PackageManagerService**,为啥要起这么“狂妄”的名字呢?其主要的原因是我希望从一个更全面、更高的、更清晰的视角来看明白**PackageManagerService**的每个**模块**之间是如何协作来保证**PackageManagerService**的关键工作顺利完成。通过本文您将了解到**PackageManagerService**被划分为哪些**模块**,**模块**之间是如何协作来保证各项工作的顺利完成。

niurenwo的专栏 1666

Android PackageManagerService源码分析和APK安装原理详解

mPM是系统中写的AIDL文件,通过mPM.getPackageInfo(),调用到代理对象Proxy类中重写的getPackageInfo()方法,代理对象又调用到PackageManagerService中的getPackageInfo()方法。首先通过adb install 输入包名后,一敲回车,会执行到commandline.c文件下的,adb_commandline()方法。1.静默安装,又叫无界面的安装,从各大手机厂商应用商店下载的APK,便是无界面的安装。

路宇的博客 1942

Android系统PackageManagerService简介

Android PackageManagerServer 应用安装过程详解,apk安装过程

BCIC IV 2a数据集实战:从MATLAB导入到EEG信号分析全流程

本文提供了BCIC IV 2a数据集从MATLAB导入到EEG信号分析的完整实战流程。详细解析了数据集结构,区分了EEG与EOG信号,并演示了信号可视化、基础预处理(滤波、分段、基线校正)等关键步骤,帮助脑机接口研究者快速上手处理这一经典运动想象数据集。

weixin_29047919的博客 469

PackageManagerService启动详解(一)之整体流程分析

终于要拉开PKMS启动详解系列博客的序幕了,当然读者最好能先阅读一下PackageManagerService启动详解系列博客概要对我们的整个系列博客有一个整体的了解。在今天的博客中我们将会从整体上来介绍PKMS的启动流程,所以我们只会重点关注PKMS的整个启动流程,让读者先从整体上有一个认识。至于在源码分析中注释的代码内容,读者可以先有一个概括,在后续的博客中我们会采取庖丁解牛的方式逐一分析。

IT先森 7137

从CPRI到eCPRI:手把手教你用Wireshark分析基站前传协议帧结构

本文手把手教你使用Wireshark工具,深入解析从CPRI到eCPRI的基站前传协议帧结构。通过搭建分析环境、编写解析脚本,并对比两者在时延管理、帧格式及数据封装上的差异,为无线通信领域的研发与测试人员提供了一套实用的逆向分析与故障排查方法。

x8y9z0的博客 604

Android源码分析(十四)PackageManagerService服务分析

一. PackageManagerService启动过程分析 PackageManagerService(PMS)主要是管理应用的安装,卸载,更新,解析以及权限。   如果想了解SystemService启动过程请看这篇文章:Android 源码分析(六) SystemServer 进程如果想了解AMS服务分析请看这篇文章:Android源码分析(十三)ActivityManagerSe...

weixin_34029680的博客 259

UE5实战:如何用Georeference插件搞定百度地图坐标转换(附完整代码)

本文详细解析了在UE5中使用Georeference插件实现百度地图坐标转换的全流程,包括BD-09到UE内部坐标的转换算法、UTM投影配置及性能优化技巧。通过完整代码示例和实战案例,帮助开发者高效解决数字孪生项目中的地理坐标转换难题。

weixin_30955617的博客 94

Simulink开发项1000例实战专栏--实例17:基于 Simulink 的 BLDC 电机驱动系统的设计与实现

项目背景无刷直流电机(BLDC)因其高效、可靠、低维护的特点,广泛应用于电动汽车、无人机、工业自动化等领域。基于 Simulink 的 BLDC 电机驱动系统可以实现对电机的精确控制,包括速度控制、位置控制和转矩控制。通过仿真和测试,可以优化控制算法,提高系统的性能和可靠性。

xiaoheshang_123的博客 562

安卓系统SystemServer启动源码分析

主线支线。

2601_95605400的博客 229

华为od 面试八股文_C++_02_含答案

华为od 面试八股文_C++_02_含答案

MISAYAONE的博客 3121

Android服务之PackageManagerService启动源码分析

了解了Android系统的启动过程的读者应该知道,Android的所有Java服务都是通过SystemServer进程启动的,并且驻留在SystemServer进程中。SystemServer进程在启动时,通过创建一个ServerThread线程来启动所有服务,本文主要介绍Android服务中PackageManagerService服务启动过程。首先介绍一些PackageManagerSer...

架构设计 134

华为HCIE之TS部分整理

TroubleShooting 整体拓扑 1. MSTP 题目需求:site1 中,CLIENT1 属于 VLAN12,CLIENT3 属于 VLAN34;MSTP 中的 VLAN12 属于 instance1,vlan34 属于 instance2;两个 instance 的主备根桥分别在 SW1 和 SW2 上,并且要求 CLIENT1访问 R1 时经过的路径是 SW3-SW1-R1;同时要求 CLIENT3 访问 R1 时经过的路径是SW3-SW2-R1; 排错思路: ①查看SW3 SW1 SW

ledrsnet的博客 5756

VTsystem背景检查函数Value Valid

Value Valid是个非常实用的函数,如何让它灵活的为我们所用,便是本文的内容。

欢迎来到eee的博客 795

Android 10.0 PackageManagerService(四)APK安装流程-[Android取经之路]

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析 [Android取经之路] 系列文章: 《系统启动篇》 Android系统架构 Android是怎么启动的 Android 10.0系统启动之init进程 Android10.0系统启动之Zygote进程 Android 10.0 系统启动之SystemServer进程 Android 10.0 系统服务之ActivityMnagerService Android10.0系统启动之Launcher(桌面)启动流程 And

纸上得来终觉浅,绝知此事要躬行 2110

24、汽车黑客技术全解析:诊断代码、车库创建与系统攻防

本文深入探讨了汽车黑客技术的核心内容,包括诊断代码模式与参数ID、创建开放车库社区、汽车系统相关技术、硬件与软件工具、攻击与防御手段,以及车辆通信与网络安全。无论你是汽车安全研究人员、爱好者还是开发者,都能从中获取全面的技术解析与实践指南。

Apple的专栏 228

2024年Java最全PackageManagerServices 源码分析,Java编程书籍推荐

这份面试题几乎包含了他在一年内遇到的所有面试题以及答案,甚至包括面试中的细节对话以及语录,可谓是细节到极致,甚至简历优化和怎么投简历更容易得到面试机会也包括在内!也包括教你怎么去获得一些大厂,比如阿里,腾讯的内推名额!某位名人说过成功是靠99%的汗水和1%的机遇得到的,而你想获得那1%的机遇你首先就得付出99%的汗水!你只有朝着你的目标一步一步坚持不懈的走下去你才能有机会获得成功!成功只会留给那些有准备的人!本文已被。

2401_84688353的博客 898

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Android PackageManager Service详解 (5.1源码) (一)

android基于linux,所以当设备上电后,初期的启动流程跟linux系统并无二致,uboot引导,接着载入kernel代码,加载各种驱动,结束后,启动第一个用户级进程init,init接着解析init.rc后,按照配置启动各种linux后台进程。    整个linux系统底层已经Ready后,接着要干嘛,当然是启动android引导进程,装载android运行环境所需的代码和资源。

拿节 1815

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

android PackageManagerService

(PMS),顾名思义,其作用就是对我们的apk安装包进行管理服务,作为Android在java层的服务之一,其与所有其他的服务一样都是由SystemServer所启动的。 package com.android.server; public final class SystemServer { } #SystemServer /** * The main entry p...

且听真言 997

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android PackageManager

这两个管理器其实没什么好扯的,看一下源代码基本上就知道了,用途的话除了系统本身用的最多,PackageManager在桌面Launcher APP使用. PackageManager管理器主要负责APP Package的管理,比如安装,卸载,Package的解析,Package包的各种信息,如版本,APP图标,资源,权限等等,android系统在安装APP的时候,会弹出一个提示框,提示框中就会显

刘志保的博客 1224

Android PackageManagerService总结(四) APK安装流程

管理本地apk,主要包括安装、删除 本篇文章重点介绍一下apk安装流程

u012514113的专栏 6465

Android PackageManagerService详细分析

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。下方即为我手绘的Android框架体系架构知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的Android框架体系架构知识脑图原件(包括上方的面试解析xmind文档)

2401_84103675的博客 1090

Android P包管理机制之PackageManager简介

1.PackageManager简介 与ActivityManager和AMS的关系类似,PMS也有一个对应的管理类PackageManager,用于向应用程序进程提供一些功能。PackageManager是一个抽象类,它的具体实现类为ApplicationPackageManager,ApplicationPackageManager中的方法会通过IPackageManager与AMS进行进程间...

marshal_zsx的博客 1998
上一篇: Android Fragment实践(三)— 使用Fragment + Loader实现异步加载
下一篇: Android 开发-电池(Battery)电量等数据的监听,用Service,Broadcaset,以及Thread的方式实现
liranke
博客等级 码龄20年 4939粉丝 594原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值