PackageManagerService安装应用流程

PackageManagerService主要负责Android系统的应用管理,它提供对各种APK文件的安装、卸载、优化和查询服务。PackageManagerService在系统启动时会扫描所有存在的APK文件和Jar包信息,并将它们读取、保存起来;这样系统在运行时,就能很快的查询到各种应用和相关组件的信息。

《PackageManagerService安装应用流程》

一、 PackageManagerService初始化

《PackageManagerService安装应用流程》

参数介绍:

Installer=>负责与installd通讯的客户端

实例化在systemServer中

《PackageManagerService安装应用流程》

FactoryTest=>是否当前系统进去的是工厂模式,这里假设走false

OnlyCore=>是否处理系统核心应用,假设走false

《PackageManagerService安装应用流程》

对应的核心应用在哪里指定:

《PackageManagerService安装应用流程》

1. 构造函数—1

《PackageManagerService安装应用流程》

添加几种SharedUserId对象到Settings中,sharedUserId属性相同的package可以运行在同一个进程中,或者相互读取资源;

Settings可以看做是一个数据动态管理类,它主要会管理packages.xml文件中的信息;

《PackageManagerService安装应用流程》

  • packages.xml:记录了系统中所有安装应用的基本信息,如果签名、权限等等
  • packages-backup.xml:packages.xml文件的备份
  • packages-stopped.xml:记录系统中所有被强制停止运行的应用的信息(如我们在系统设置中,选择某个应用,并将它强制停止)
  • packages-stopped-back.xml:packages-stopped.xml文件的备份
  • packages.list:保存了应用的数据目录和UID等信息

Android系统在修改packages.xml、packages-stopped.xml之前,会先对它们进行备份。当对它们的修改操作正常完成,则会删掉之前建立的备份文件。如果,在修改过程中系统出现问题重启了,会再次去读取这两个文件。

2. 构造函数—2

《PackageManagerService安装应用流程》

SystemConfig是一个工具类,它负责读取系统中全局的某些权限、特性信息,展开SystemConfig,看做了什么:

《PackageManagerService安装应用流程》

通过readPermissions()读取指定/system/etc/、/oem/etc/等目录下的permission xml文件,解析其中的内容。

《PackageManagerService安装应用流程》

我们列举一些其中的文件的内容,来大致看下配置文件的内容:

platform.xml

《PackageManagerService安装应用流程》

 

《PackageManagerService安装应用流程》

《PackageManagerService安装应用流程》

plateform.xml中出现的标签种类则较为多样,它们的含义分别是:

  • <permission >标签:把属性name所描述的权限赋予给<group>标签中属性gid所表示的用户组
  • <assign-permission>标签:把属性name所描述的权限赋予给uid属性所表示的用户
  • <library>标签:除framework中动态库以外的,所有系统会自动加载的动态库

最后将上面xml解析出来的数据做如下存储:

  • <group>标签gid属性的值会存放在mGlobalGids数组中;
  • <permission>标签,解析得到的值会存放在mPermissions集合中;
  • <assign-permission>标签解析得到的值会存放在mSystemPermissions中;
  • <library>标签解析得到的值会存放在mSharedLibraries中;
  •  
  • 3. 构造函数—3

  • 该部分介绍apk扫描过程

  • 《PackageManagerService安装应用流程》PackageManagerService(PKMS)构造中触发APK扫描的函数调用是:scanDirTracedLI(),它会遍历我们传入的文件路径,然后循环解析其中存在的APK文件,并将信息解析出来存入PKMS内部,供后续的运行时信息管理。PKMS这一部分的函数调用很深,我们这里只看其中的几个关键函数调用,以此来熟悉APK扫描工作的基本内容。

  • PKMS解析APK文件主要依靠PackageParser实现.

     

    其中,PackageParser::Package信息是最丰富的。说是解析APK文件,其实主要是解析应用的Androidmanifest.xml配置文件;因为配置文件中描述了所有有关该应用的组件、权限、包名等信息。对它的解析过程,就是我们获取APK信息的过程。

    PackageParser::parseBaseApkCommon()负责Androidmanifest.xml的解析,将生成的信息保存到PMS的相关变量中

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 我们只看里面关于application标签的解析。

  • 《PackageManagerService安装应用流程》

  • 调用parseBaseApplicaton()函数解析<application>标签。

  • 《PackageManagerService安装应用流程》

  • 我们从代码中看到了对Application中声明的Android四大组件的解析调用,它们的解析过程类似:都是调用XmlPullParser解析器解析各个节点的内容并保存。我们以解析Activity为例,来看它是如何解析<activity>节点、并保存其各个节点的信息的,以<intent-filter>节点的内容;我们设置的intent内容都包含在<intent-filter>节点内,PMS对外提供了组件查询的业务,它主要就是根据这里的intent来查找的。:

  • 《PackageManagerService安装应用流程》

  • 解析到了Intent信息会保存到Activity实例内部的intents集合中;这一部分对Service/Provider/Receiver的解析都是一样的;<activity>标签解析完后,返回的activity实例又会被保存到Package类的activities中。其他三大组件的处理也跟此类似,所以这里就略过它们的解析过程了。

    parseBaseApplication()函数执行完毕后,我们得到了一个保存有绝大部分APK信息的Package实例;得到了Package实例,我们还需要把它的信息整合到PMS中,让PMS统一管理;这个过程由PMS::scanPackageDirtyLI()处理。scanPackageDirtyLI()函数的处理较长,这里不做详细分析。

    经过了scanPackageDirtyLI(),我们解析到的一个APK的Package实例添加到了PMS中,并且它所有重要组件也已经由PMS统一管理。这样PMS就能很好的管理这个APK的信息了。

    到这里,APK扫描所涉及到的主要函数调用分析也就结束了。

     

    二、 apk安装

    不管是三方市场,或系统自带的packageInstaller,其实到后面的动作都是一样的,我们这里以最复杂的adb install来分析流程。

    在android中,adbd以后台进程运行。当我们输入”adb install”命令时,/syste/core/adb/目录下commandline.cpp文件会被执行,其中adb_commandline()函数会接受该条指令,并进行处理,这里只看install命令的执行:

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 然后,流程会去执行pm脚本进行安装操作。手机的端的adbd程序接收到客户机发送的shell pm命令后,会开启一个shell去执行pm脚本。pm脚本的内容如下:

  • 《PackageManagerService安装应用流程》

  • frameworks\base\cmds\pm\src\com\android\commands\pm\Pm.java

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 最终还是调用到PMS里面,层层调用,最后来到installPackageAsUser()

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  •  

    进入handleStartCopy后:

  • 首先会进行一些安装标志的判断
  • 调用DCS::getMinimalPackageInfo()方法获取该apk安装需要的大小及其他信息
  • 如果检测到当前的目录下的大小不足以安装应用,还回去进行cache的清理工作
  • 随后会以当前的InstallParams实例,创建FileInstallArgs对象,并保存一份到InstallParams对象的mArgs字段中
  • 后续是一段组件校验工作,这里不做分析
  • 最后FileInstallArgs::copyApk()函数,进行下一步处理
  • handleStartCopy最终调用到doCopyApk,完成下面动作:

  • 通过PackageInstallService为要安装的apk在/data/app/下生成一个零时文件tempDir
  • 为该tempDir创建IParcelFileDescriptorFactory文件描述符,它可以在进程间传递
  • 调用DefaultContainerService::copyPackage()方法执行apk临时文件的复制
  • 最后再将apk中包含的一些库文件提取出来,放置到对应的lib/目录下
  • 如果一切过程都正常,至此,APK安装的第一部分的工作:APK文件的拷贝,就结束了,接着处理下一步:

  • 《PackageManagerService安装应用流程》
  • 《PackageManagerService安装应用流程》
  • processPendingInstall->installPackageTracedLI

    ->installPackageLI->installNewPackageLIF->scanPackageTracedLI

    >scanPackageLI->scanPackageDirtyLI  完成信息的整合

     

    在Android系统中,PackageManagerService用于管理系统中的所有安装包信息及应用程序的安装卸载,但是应用程序的安装与卸载并非PackageManagerService来完成,而是通过PackageManagerService来访问installd服务来执行程序包的安装与卸载的。

  • 《PackageManagerService安装应用流程》

  • Android O上面installd与PMS直接的通讯已经由socket换为binder了。

    Installd服务的启动在systemServer中:

     

    相关实现在:

    frameworks\native\cmds\installd\installd.cpp

    frameworks\native\cmds\installd\InstalldNativeService.cpp

    frameworks\base\services\core\java\com\android\server\pm\Installer.java

  • 《PackageManagerService安装应用流程》

  • frameworks\native\cmds\installd\installd.rc

    service installd /system/bin/installd
        class main

    相关执行最终在installd中完成。

  • 《PackageManagerService安装应用流程》

  • 《PackageManagerService安装应用流程》

  • 处理结束后,发送相关广播通知其他应用,如launcher收到广播后,通过PMS查找先关activity,显示图标等信息。

  • 《PackageManagerService安装应用流程》

  •  

  •  

  • 《PackageManagerService安装应用流程》到此apk安装结束。

  •  
    原文作者:AK_Coffee
    原文地址: https://blog.csdn.net/chi_wy/article/details/82147620
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞