一、概述
1、应用冷热启动的区别
(1)冷启动:当启动一个应用时,后台没有该应用的进程,这时系统会创建一个新的进程分配给该应用,这个启动方式就是冷启动。
由于系统会创建一个新的进程分配给它,所以会先创建和初始化 Application 类,再创建和初始化 MainActivity 类,包括:测量(measure)、布局(layout)、绘制(draw),最后显示在界面上。
(2)热启动:当启动一个应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入后台任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。
由于会从已有的进程中来启动,所以热启动就不会走 Application 这步了,而是直接走 MainActivity,包括:测量(measure)、布局(layout)、绘制(draw),所以热启动的过程只需要创建和初始化一个 MainActivity 就行了,而不必创建和初始化Application。
备注:观察一个应用启动的 Systrace,看启动应用的 UI thread 是否有 bindapplication 函数,有则为冷启动。
二、冷启动
1、整个过程
一般测试 case 的前提条件:清除所有后台,关闭需要测试应用的自启动开关。
从手指抬起到应用铺满整个界面或者界面完全显示不动,其中应用经历了如下过程:
应用冷启动整个过程从Systrace上如下:
对应Systrace中的几个点分别为:
system_server进程: iq事件 → App进程 UI thread: postFork → App进程 UI thread: ZygoteInit → App进程 UI thread: ActivityThreadMain → App进程 UI thread: bindApplication → App进程 UI thread: activityStart → App进程 UI thread: activityResume → App进程 UI thread: doframe。
2、分析步骤
(1)确认测试机和对比测试环境是否一致:
<1> 检查 Android 大版本;
<2> 检查 是否为 root 版本;
<3> 检查 硬件差异:CPU、GPU、EMMC、文件系统(ext4 or f2fs);
<4> 检查 测试 Apk 的版本。
(2)分解启动过程中的每个阶段
各函数分解出来后,找出具体的耗时阶段,先观察过程中是否流程一致,Android 大版本升级,可能会导致启动流程不一致,比如:某些应用在 Android Q 上会有 service create 的过程,但是在其他 Android 版本是另起线程进行 service create。这种问题需要反馈给三方应用去检查。
(3)找到耗时增加的阶段,检查函数运行状态
如下图,选中启动过程中耗时增加的函数,再次进行分解:
统计如下:
(4)针对具体耗时增加的状态分析
3、具体耗时状态分析
(1)差异在Running阶段 (Systrace上表现为绿色)
该问题主要需要检查机器的如下配置:
<1> 检查应用的编译模式:
执行:$ adb shell dumpsys package [应用包名]
使用dex2oat进行AOT(Ahead-Of-Time:运行前编译)编译的 compile filter:
-verify:只运行 DEX 代码验证。
-quicken:运行 DEX 代码验证,并优化一些 DEX 指令,以获得更好的解释器性能。
-speed-profile:运行 DEX 代码验证,并对配置文件中列出的方法进行 AOT 编译。
-speed:运行 DEX 代码验证,并对所有方法进行 AOT 编译。
三方应用目前基本上使用的编译模式都是:speed-profile。
若发现编译模式不一致的情况,可以使用:$ adb shell cmd package compile -c -f -m speed [应用包名]
,将应用强制进行 speed 编译,确认是否是编译模式导致。
如果确认是编译模式不一致导致,下面的一些优化需要看下是否合入:
class loader :http://gerrit.pt.mioffice.cn/#/c/331753/
应用启动编译优化 :
http://gerrit.pt.mioffice.cn/c/platform/art/+/432624
http://gerrit.pt.mioffice.cn/c/platform/frameworks/base/+/432652
http://gerrit.pt.mioffice.cn/c/miui/frameworks/base/+/551355
http://gerrit.pt.mioffice.cn/c/miui/frameworks/base/+/751982
<2> 检查应用的插件编译模式
带上如下change打包:http://gerrit.pt.mioffice.cn/c/platform/art/+/276849
搜索 “miui_dex2oat: --dex-file=xxx --compiler-filter=xxx” 字样,确认插件编译方式。
若发现插件编译模式不一致的情况,可以使用:$ adb shell cmd package c