Android 8.1 应用安装过程总结

整体介绍

一个 Android 应用安装到手机上大致分为四种情形:

  • 系统应用,在设备每次启动时完成安装
  • 通过 adb install 命令安装
  • 应用市场安装,封装安装过程(略)
  • 第三方应用安装或双击安装包,会启动系统应用引导安装

无论采用哪种安装方式,最终的安装过程都会走到 PackageManagerService,由这个类来完成一系列的工作。
PackageManagerService 实际上是一个系统服务,负责提供系统上所有应用的管理,包括安装、优化、查询和卸载,这个类最终会通过 socket 与 installd 这个守护进程通信,真实对应用进行操作的其实是由 installd 这个进程完成。

场景一:系统应用安装

在设备启动时,Linux 系统的用户空间进程 init (pid = 1)会孵化许多子进程,包括一系列守护进程,其中就有上面提到的 installd,然后会孵化许多重要的系统服务,如 servicemanager,这个进程会负责管理所有服务的 Binder 通信,此外 init 还会孵化mediaserver,此进程负责启动和管理 Framework 的 C 层的服务,最后 init 还会孵化 zygote 进程,这个进程是第一个 Java 进程,zygote 进程会孵化出许多应用程序进程,包括 launcher 进程,即桌面进程,zygote 还会孵化出 system_server 进程,这个进程与 mediaserver 对应,负责启动和管理 Framework 的 Java 层服务,包括 PackageManagerService、ActivityManagerService 等
init孵化进程
补充:system_server 的启动与运行流程

system_server 由 zygote 进程孵化,是整个 Android Framework 的基础

zygote 启动阶段会调用 forkSystemServer() 创建子进程 system_server
zygote启动system_server
ForkAndSpecializeCommon 函数中完成进程创建工作并返回,两次返回,pid=0 时为子进程,pid>0 时为父进程。onZygoteInit() 回调的实现在在 app_main.cpp 中,会调用 ProcessState::self() 初始化 binder 的交互操作,然后调用 proc->startThreadPool() 创建 binder 线程进行通信

RuntimeInit 的 findStaticMain() 调用 com.android.server.SystemServer 的 main 方法

SystemServer 的 run() 方法中会完成以下工作:

  • 设置时间、语言等,设置虚拟机库文件,设置内存
  • Looper.prepareMainLooper() 主线程 looper 运行在当前线程
  • 加载库文件 android_servers,位于 /frameworks/base/services
  • createSystemContext() 初始化系统上下文
  • SystemServiceManager() 创建系统服务管理器,并添加到本地服务成员 LocalServices 中
  • 启动各种系统服务,包括引导服务、核心服务、其他服务
  • 开启循环,等待其他线程通过 handler 发送消息到主线程来处理

在 system_server 进程启动过程中会启动各种系统服务,其中就包含 PackageManagerService
system_server启动PMS
PackageManagerService 类构造函数中完成了许多工作,主要包含:

  • 创建 Settings 对象,添加系统的 SharedUser 信息
  • 为 Installer 对象赋值,赋值参数是在 system_server 进程中创建的
  • 创建 PackageDexOptimizer 和 DexManager 对象
  • 获取 SystemConfig 实例,获取系统的全局配置信息,如 GlobalGids、SystemPermissions、AvailableFeatures
  • 创建 ServiceThread 和 PackagerHandler 对象
  • 创建 UserManagerService,支持多用户
  • 读取系统定义的权限保存到 permConfig 变量中
  • 读取系统共享库保存到 libConfig 变量中
  • 解析 package.xml 文件中的内容保存到 ArrayMap<String, PackageParser.Package> 结构中
  • 配置扫描参数 scanFlags
  • 开始扫描系统应用,包括目录 /vender/overlay、/system/framework、/system/priv-app、/system/app、/vendor/app、/oem/app
  • 开始扫描非系统应用,包括目录 /data/app、/data/app-private
  • 启动内存垃圾回收
  • 启动私有服务 PackageManagerInternal

总结来说主要是这几项内容:

  • 创建了 Java 层 Installer 和 C 层 installd 之间的 socket 连接
  • 扫描各目录下 apk文件完成安装(建立各安装包的配置结构信息,并添加到全局列表中进行管理)
  • 创建了 PackageHandler 对象并建立消息循环,接收外部的安装请求
  • 解析权限,建立底层 Linux Kernel 的用户机制和虚拟机层权限机制之间的映射
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值