深度探究apk安装过程

Posted fesng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度探究apk安装过程相关的知识,希望对你有一定的参考价值。

一.先验知识

0.PcakageaManagerService版本变化
1.概述
2.PackageManagerService服务启动流程
3. PackageManagerService入口

二.四种安装方式

1.系统应用安装2.网络下载应用安装3. ADB工具安装
4.第三方应用安装

三.总结

这里写图片描述

概述

1.1概述
众所周知,android应用最终是打包成.apk格式(其实就是一个压缩包),然后安装至手机并运行的。APK即Android Package的缩写。
Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息,完成应用程序的安装过程。
应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。

Android应用APK安装的方式

一般而言,Android应用安装有如下四种方式:
系统应用安装:开机时加载系统的APK和应用,没有安装界面;
网络下载应用安装:通过各种market应用完成,没有安装界面;
ADB工具安装:即通过Android的SDK开发tools里面的adb.exe程序安装,没有安装界面;
第三方应用安装:通过SD卡里的APK文件安装(比如双击APK文件触发),有安装界面,系统默认已经安装了一个安装卸载应用的程序,即由packageinstaller.apk应用处理安装及卸载过程的界面。

应用安装涉及到的目录

/system/app :系统自带的应用程序,获得adb root权限才能删除
/data/app :用户程序安装的目录。安装时把apk文件复制到此目录
/data/data :存放应用程序的数据
/data/dalvik-cache:将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,当然,ART–Android Runtime的可执行文件格式为oat,启用ART时,系统会执行dex文件转换至oat文件)
/data/system :该目录下的packages.xml文件,类似于Windows的注册表,这个文件是在解析apk时由writeLP()创建的,里面记录了系统的permissions,以及每个apk的name,codePath,flags,ts,version,uesrid等信息,这些信息主要通apk的AndroidManifest.xml解析获取,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存相关列表中。当有apk升级,安装或删除时会更新这个文件。
/data/system/packages.xml中内容详解(这里列举的标签内容不一定完整,只是列举核心内容,packages.xml的完整定义详见官方文档):

安装概述

(1) 拷贝apk文件到指定目录
在Android系统中,apk安装文件是会被保存起来的,默认情况下,用户安装的apk首先会被拷贝到 /data/app 目录下。
/data/app目录是用户有权限访问的目录,在安装apk的时候会自动选择该目录存放用户安装的文件,而系统出厂的apk文件则被放到了 /system 分区下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,该分区只有Root权限的用户才能访问,这也就是为什么在没有Root手机之前,我们无法删除系统出厂的app的原因了。
(2) 解压apk,拷贝文件,创建应用的数据目录
为了加快app的启动速度,apk在安装的时候,会首先将app的可执行文件(dex)拷贝到 /data/dalvik-cache 目录,缓存起来。
然后,在/data/data/目录下创建应用程序的数据目录(以应用的包名命名),存放应用的相关数据,如数据库、xml文件、cache、二进制的so动态库等等。

(3) 解析apk的AndroidManifinest.xml文件
Android系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件。这个文件位于如下目录:
/data/system/packages.xml
系统在安装apk的过程中,会解析apk的AndroidManifinest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。
由此,我们就知道了为啥一些应用市场和软件管理类的app能够很清楚地知道当前手机所安装的所有的app,以及这些app的详细信息了。
另外一件事就是Linux的用户Id和用户组Id,以便他可以获得合适的运行权限。
以上这些都是由PackageServiceManager完成的,下面我们会重点介绍PackageServiceManager。
(4) 显示快捷方式
这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了

1.2 PackageManagerService启动过程

这里写图片描述

1.3 PackageManagerService入口

这里写图片描述

2.1系统应用安装方式

这里写图片描述

2.1系统应用安装方式

第一步:1.PackageManagerService.main()初始化注册

将PackageManagerService服务初始化并注册到ServiceManager里面进行管理。

第二步:2.建立java层的installer与c层的installd的socket联接

建立java层的installer与c层的installd的socket联接,使得在上层的install,remove,dexopt等功能最终由installd在底层实现;

第三步:3.建立PackageHandler消息循环

建立PackageHandler消息循环,用于处理外部的apk安装请求消息,如adb install,packageinstaller安装apk时会发送消息;
典型的比如INIT_COPY和MCS_BOUND等,在通过网络下载时候会调用。

第四步:4. 成员变量readLp()恢复上一次的安装信息

由于Android每次启动的时候都需要安装一次信息,但是有些信息是保持不变的,例如Linux用户组Id,PackageManagerService 每次安装程序之后,都会把这些程序的信息保存下来,以便下次使用, 恢复上一次程序的安装信息是通过PackageManagerService 的成员变量mSetting的readLP()来实现的,恢复信息之后就开始扫描和安装app了。
检查/data/system/packages.xml是否存在,这个文件是在解析apk时由writeLP()创建的,里面记录了系统的permissions,以及每个apk的name,codePath,flags,ts,version,uesrid等信息,这些信息主要通过apk的AndroidManifest.xml解析获取,解析完apk后将更新信息写入这个文件并保存到flash,下次开机直接从里面读取相关信息添加到内存相关列表中。当有apk升级,安装或删除时会更新这个文件。

第五步:5.jar的detopt优化

检查BootClassPath,mSharedLibraries及/system/framework下的jar是否需要dexopt,需要的则通过dexopt进行优化;

第六步:6.scanDirLI函数扫描特定目录的apk文件解析

启动AppDirObserver线程监测/system/framework,/system/app,/data/app,/data/app-private目录的事件,主要监听add和remove事件。对于目录监听底层通过inotify机制实现,inotify 是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知,它为用户态监视文件系统的变化提供了强大的支持。当有add event时调用scanPackageLI(File , int , int)处理;当有remove event时调用removePackageLI()处理;

调用installer.install()进行安装工作,检查apk里的dex文件是否需要再优化,如果需要优化则通过辅助工具dexopt进行优化处理;将解析出的componet添加到pkg的对应列表里;对apk进行签名和证书校验,进行完整性验证。

第七步:7.updatePermmisonLp函数分配权限

这个函数为申请了特定资源访问权限的app,分配相应的用户组ID.

第八步:8.writeLP()函数保存安装信息

mSetting的writeLP()将所获得应用程序的安装信息,保存在一个本地的配置文件中。以便下次安装的时候,将应用的信息回复过来。

2.1系统应用安装方式

这里写图片描述

2.2网络下载应用安装

这里写图片描述

2.3 ADB工具安装

这里写图片描述

2.4第三方应用安装

![这里写图片描述](https://img-blog.csdn.net/20170310214918051?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHBqaXNodQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/

三.总结

1.安装和卸载都是通过PackageManager,实质上是实现了PackageManager的远程服务PackageManagerService来完成具体的操作,所有细节和逻辑均可以在PackageManagerService中跟踪查看;

2.所有安装方式殊途同归,最终就回到PackageManagerService中,然后调用底层本地代码的installd来完成。

再看apk 的安装过程。
回个我们再看真个apk的安装过程,主要分为如下几部
拷贝apk文件到指定目录
解压apk,拷贝文件,创建应用的数据目录
解析apk的AndroidManifinest.xml文件
向Launcher应用申请添加创建快捷方式

参考:
《Android源代码情景分析》
《Android内核分析》
http://blog.csdn.net/luoshengyang/article/details/6766010
http://blog.csdn.net/hdhd588/article/details/6739281
http://ticktick.blog.51cto.com/823160/1669525
http://www.jianshu.com/p/953475cea991
http://cstsinghua.github.io/2016/06/13/Android%E5%AE%89%E8%A3%85APK%E8%AF%A6%E8%A7%A3/
http://junshengluo.com/2016/11/30/android-5-%E6%8E%A2%E7%A9%B6%20Android%20%20apk%20%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/

以上是关于深度探究apk安装过程的主要内容,如果未能解决你的问题,请参考以下文章

Android:了解APK安装过程

从APK安装过程来认识PMS

APK安装过程及原理详解

C++学习(四一九)apk安装过程

[android]android下apk的安装过程

❤️Android 从源码解读 Apk 的安装过程 ❤️