网上关于启动优化的分析等文章应该很多了,比如启动时序、耗时统计、分析工具啥,这里就不再过多说明。本文旨在告诉你如何有效进行系统优化启动(分析版本Android P),仅供参考。
目录
Android系统正常开机时序
zygote
systemserver
服务启动阶段(优化)
PMS扫描(优化)
服务就绪阶段
用户数据解锁 提前解锁用户数据(优化)
关于预读
上电 > bootloader > kernel > init > file system mount > zygote > system server
既然叫FW启动优化说明,那这里不对zygote之前的流程做分析。
网上文章应该也不少,比如异步、延迟加载资源。而google源码就已经实现了延迟加载,至于是否异步,则取决与CPU性能,因为zygote最后会拉起systemserver进程,资源异步加载可能会影响systemserver进程创建(而且后续systemserver进程也会启动大量系统server),而导致整体启动时间拉长。
上面说了它会启动大量server,此过程大概需要5-6s左右,此阶段又可以分二个阶段来看,systemReady之前的服务启动阶段(服务启动) + 最后systemReady阶段(服务就绪)。
google默认是通过串行 + 并行方式启动系统服务,但是考虑到服务的依赖关系,并行的服务数量很少,这里存在一定优化空间,即并行启动一些服务。(当然还可以裁剪部分原生服务)。
这里需要特殊说明一些PMS服务,它占据整个服务启动阶段大量时间,主要花费在pkg扫描、解析上,基于此,可以对解析做一个缓存策略,从而优化解析时间,缩短整个PMS启动时间。(详情见PackageParser.java,google其实原生已实现了此策略,但由于时间戳问题,导致并没有生效)
此阶段相对之前流程比较复杂,建议跟着代码流程,在关键部分加日志以理清其逻辑关系(至少需要知道是如何从systemReady启动Launcher的)。
这里为了方便理解,简要说明一下用户数据解锁概念(可以认为是 用户解锁 的子集),在高版本的Android系统中,基于安全考虑,在系统启动之前,需要对用户数据做解锁。之后就可以启动系统常规的应用了,如果想在数据解锁之前启动,可以通过配置
android:directBootAware="true"
来实现,但是此时启动的应用不能访问数据。(FallbackHome就是如此)
假设你已理解从systemReady到启动Launcher流程,就可以知道启动launcher前最后一个步骤就是解锁用户数据,然后拉起系统正常(非bootAware)服务。那么如果可以提前解锁用户数据,意味着你可以跳过启动FallbackHome动作,直接启动Launcher,虽然Launcher非bootAware,但是用户数据已解锁,所以此时启动也完全正常,可以访问用户数据。
用户数据解锁动作可以提前至systemserver启动服务阶段,注意由于此过程比较耗时,需要异步执行。然后在systemReady时,就可以快速启动真实UI(比如launcher或其它定制化界面等)。
看起来是不是很简单?但是这里有如下几个问题需要对应:
最后本文只是列出优化思路,没由对具体步骤做详细说明。
======================================2020.6.12更新================================================
采用预读机制(treadhead)来减少启动时间,是否采用,需要根据实际情况来看,即根据当前系统 bootchart 的IO Wait来定,如果在启动过程中出现大量IO Wait,则可以尝试采用此优化机制,原理就不说了,网上也有不少类似文章,本人在项目中实际测试,(部分系统)大概可以减少1-2s左右。下面是具体操作流程,自取:
源码:bionic/libc/treadahead-1.3 (需要新建目录)
编译:有二个模块mincore、treadahead,按照模块方式编译集成即可.
├── Android.mk 编译脚本
├── mincore 可执行
├── mincore.c 源码
├── readahead.S 无用
├── treadahead 可执行
└── treadahead.c 源码
用法:
先将可执行文件push到/system/bin
1. 生成预读文件,如预读当前目录下的所有apk文件,并将文件生成到/system/etc目录
find -name "*.apk" | xargs mincore > /system/etc/treadhead.txt
(mincore代码实现不全,只能通过其它方式来生成,读者可自行完善)
2. 预读命令 treadahead -f/system/etc/treadhead.txt
如果需要实机测试,需要通过rc文件方式自启动,注意要加到init.rc合适位置(fstab之后)。
资源:https://download.csdn.net/download/pshebing/12517742
参考:https://www.baidu.com/link?url=4L0QRd2Iyz__TWkjUT-HXhfnnKX9hXRjqwpc7NNeIlUGYxsNs7IW8LftK0iIUvGX5qjLVukOlFFLY2488b2xo_&wd=&eqid=cb1cba3e0000f501000000055ee323e9