type
status
date
slug
summary
tags
category
icon
password
Android系统的代码总是在不断迭代的,具体的类和方法本身并不重要,关键是了解流程与主要的路径
本文基于AOSP master分支 2020年8月,Android 11 已经处于beta版

三种安装方式

  • 系统级app安装
  • 普通app安装
  • adb安装
这里看一下普通APP的安装.
在分析之前,想一下如果是我们来安装apk,需要怎么做:
  1. apk实际上是一个zip包,先解压,要不然只能测量下大小了,当然也可以不解压直接查看zip包的内容
  1. 系统重启之后我们依然要快速显示和启动app,那么肯定得存一份APP信息到手机上,那么存什么信息呢?
      • 可执行文件的位置,在Android里跑的是dex,或者dex处理过后的机器码,因此这里应该是dex或者oat文件的位置
      • 应用有一些特殊的功能,比如可以用来打开文档,网页等,因此需要把这些信息注册到一个系统表里,可以快速查询,Android中应也有这么一个表
      而且最好是把apk的资源,可执行文件等内部数据放到一个文件夹下,这样卸载的时候可以直接删除目录.
  1. zip包解压了,信息也存了,为了安全,应该把对应的可执行文件和资源文件复制到指定的路径,如果有so库,还要让程序知道去哪里找so文件
  1. 检查手机上之前是否已经安装了这个app,如果安装了,比较一下版本,签名,再确定怎么处理
  1. 删除apk包以节省空间

APK解压缩

APK的解析在Java中的入口在PackageParser中,但是实际解压的操作在Native层,也就是ApkAssets中,ApkAssets中会调用libziparchive库去解压缩APK.
解压的具体的过程就不分析了,使用解压库就行,来看下Manifest.xml信息的提取.
ApkAssets.java中有:
frameworks/base/core/jni/android_content_res_ApkAssets.cpp中有:
AppAssets.cpp中有:
Android中的资源主要是Deflate和Stored两种压缩方式,其中Stored实际并不压缩数据,只是转换成字节数据存储而已.
Manifest.xml使用了Deflate压缩算法进行压缩,因此这里需要对应的解压出来.
其他的几个步骤,在零零碎碎的源码中找吧.

普通APP安装

先看一个简单的下载并安装apk的例子:
这里使用ACTION_VIEW,最终会调用到PacakgeInstaller APP中.
Android 10的PacakgeInstaller源码在framworks/base/packages/PackageInstaller下,看一下它的Manifest.xml来确定下谁是入口:
可以看到PackageInstaller支持的action以及协议,即content协议和package协议.
进入了InstallStart之后,根据状态的不同可能会经过InstallStaging等页面后进入到PacakgeInstallerActivity,然后就是不同的安装进度了,InstallInstallingInstallFailedInstallSuccess:
来看一下关键的对象:
然后就是开始安装APP了:
来看下InstallInstalling中的处理逻辑:
将信息保存到SessionParams中,并返回一个sessionId,后面会用到这个sessionid,在onResume的时候会启动一个后台任务去读取APK文件:
这里主要是读取APK文件到Session中,并更新安装进度.读取完毕之后发送一个广播.
此处的关键是就是session.commit()方法.
这里会调用PackageManagerService中.首先进入的是Copy阶段:

复制APK

这个copy阶段会进行一些判断,比如存储空间是否足够,如果不够会试图清理一下缓存,如果之前已经存在了APK,则直接覆盖,但是如果存在APK验证器,则必须在copy之前进行验证,只有验证通过之后才可以开始复制APK.
APK会被复制到/data/app下:
实际的copy过程如下,使用了FileDescriptor:
复制之前,会使用PacakgeParser解析APK中的mannifest文件,得到一些应用信息,并且还会获取签名信息.
然后就是复制apk文件,并且复制APK中的so文件到指定的路径.
复制完成之后,进入下一阶段processPendingInstall(mArgs, mRet);

安装APK

对于包含split APP的安装过程暂时不分析,这里指分析单个完整APK的安装流程.
实际安装步骤在installPackagesLI(requests):
这里分为4个步骤:
  1. prepare
    1. 使用PackageParser解析APK,获取各种信息,检查是否有静态共享库,有的话放在内部存储中.决定安装方式(更新,还是新安装)之类的逻辑.
  1. scan
    1. 扫描APK,更新共享库和Settings信息
  1. reconcile
    1. 新旧包以及签名相关的逻辑
  1. commit
    1. 更新设置
其实都是对APK文件进行一系列的检查验证,以确保最后可以安装成功.然后就是真实的安装了:
这里主要分为两部:
  1. 调用Installer创建APP数据
  1. 如果so库是32为,创建symlink,64位的so库不需要
Installer中的操作基本上都是委托给守护进程installd去完成的.
Installer中通过Binder机制获取到intalld服务,真实的执行逻辑在native层:

总结

  1. 应用发出Intent,要求应用内安装APK;
  1. PackageInstaller APP 中的InstallStartActivity接收到Intent,解析数据;
  1. 转到PackageInstallerActivity展示界面,用户确认之后开始进入安装过程;
  1. 请求PackageManagerService去完成安装,这里会复制APK到指定目录中,并进行签名验证
  1. 通过binder机制请求installd守护进程去完成安装过程.
Android APP启动流程分析AOSP构建-Android.bp的理解
Loading...