Activity底层知识之PMS及App安装过程透彻分析

前言:

PMS,全称PackageManagerService,是用来获取Apk包的信息的。它负责系统中Package的管理,应用程序的安装、卸载、信息查询等。

PackageManagerService及客户端的类家族如图:

《Activity底层知识之PMS及App安装过程透彻分析》 image

在下载并安装App的过程,会把Apk存放在data/app目录下。

Apk是一个zip压缩包,在文件头会记录压缩包的大小,所以后续在文件尾巴就算是追加一部小电影,也不会对解压造成影响——木马其实就是这个思路,在可执行文件exe尾巴上挂一个木马病毒,执行exe的同时也会执行这个木马,然后你就中招了。

我们可以把木马思想运用在Android多渠道打包上。在比较老的Android 4.4版本中,我们会在Apk尾巴上追加几个字节,来标记Apk的渠道。Apk启动的时候,从apk中的尾巴上读取这个渠道值。

后来Google也发现这个安全漏洞了,在新版本的系统中,就会在Apk安装的时候,检查Apk的实际大小,看这个值与Apk的头部记录的压缩包大小,是否相等,不相等就会报错说安装失败。

每次从apk中读取资源,并不是先解压再找图片资源,而是解析apk中的resources.arsc文件,这个文件中存储资源的所有信息,包括资源在apk中地址、大小等。不解压apk的好处自然是节省空间。

App的安装流程

Android系统使用PMS解析这个Apk中的manifest文件,包括:

  • 四大组件的信息,比如说,前面讲过的静态Receiver。比如说默认启动的Activity。

  • 分配用户Id和用户组Id。用户Id是唯一的,因为Android是一个Linux系统。用户组Id指的是各种权限,每个权限都在一个用户组中,比如读写SD卡,比如网络访问,分配了哪些用户组Id,就拥有了哪些权限。

  • 在Launcher生成一个icon,icon中保存着默认启动的Activity的信息。

  • App安装过程的最后,是把上面这些信息记录在一个xml文件中,以备下次安装时再次使用。

在Android手机系统每次启动的时候,都会使用PMS,把Android系统的所有apk都安装一遍,一共四个步骤。

《Activity底层知识之PMS及App安装过程透彻分析》 image

  • 第1步,因为结束安装的时候,都会把安装信息保存在xml文件中,所以Android系统再次启动时,再次重新安装所有的Apk,就可以直接读取之前保存的xml文件了。

  • 第2步,从5个目录中读取并安装所有的apk。

  • 第3步和第4步,与单独安装一个App的步骤是一样的。

应用程序的完整安装过程图:

《Activity底层知识之PMS及App安装过程透彻分析》 image

PackageParser

Android 安装一个APK的时候首先会解析APK,而解析APK则需要用到一个工具类,这个工具类就是PackageParser

/**
 * Parser for package files (APKs) on disk. This supports apps packaged either
 * as a single "monolithic" APK, or apps packaged as a "cluster" of multiple
 * APKs in a single directory.
 * <p>
 * Apps packaged as multiple APKs always consist of a single "base" APK (with a
 * {@code null} split name) and zero or more "split" APKs (with unique split
 * names). Any subset of those split APKs are a valid install, as long as the
 * following constraints are met:
 * <ul>
 * <li>All APKs must have the exact same package name, version code, and signing
 * certificates.
 * <li>All APKs must have unique split names.
 * <li>All installations must contain a single base APK.
 * </ul>
 *
 * @hide
 */
public class PackageParser {


大体意思如下:

解析磁盘上的APK安装包文件。它既能解析一个”单一”APK文件,也能解析一个”集群”APK文件(即一个APK文件里面包含多个APK文件)。
一个”集群”APK有一个”基准”APK(base APK)组成和其他一些”分割”APK(“split” APKs)构成,其中这些”分割”APK用一些数字来分割。这些”分割”APK的必须都是有效的安装,同时必须满足下面的几个条件:

  • 所有的APK必须具有完全相同的软件包名称,版本代码和签名证书
  • 所有的APK必须具有唯一的拆分名称
  • 所有安装必须包含一个单一的APK。

所以我们知道PackageParse类,它主要用来解析手机上的APK文件(支持Single APK和MultipleAPK),解析一个APK主要是分为两个步骤:

  • 将APK解析成Package:即解析APK文件为Package对象的过程。
  • 将Package转化为PackageInfo:即由Package对象生成Package对象生成PackageInfo的过程。

在插件化编程中,我们反射PackageParser,一般用来获取AndroidManifest中的四大组件信息。

参考:

声明:此为原创,转载请联系作者

作者:微信公众号添加公众号-遛狗的程序员 ,或者可以扫描以下二维码关注相关技术文章。

《Activity底层知识之PMS及App安装过程透彻分析》 qrcode_for_gh_1ba0785324d6_430.jpg

当然喜爱技术,乐于分享的你也可以可以添加作者微信号:

《Activity底层知识之PMS及App安装过程透彻分析》 WXCD.jpeg

    原文作者:遛狗的程序员
    原文地址: https://www.jianshu.com/p/620eb3a58dd6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞