Kahn's blogs

测试App启动速度脚本

2024/10/09

测试App启动速度脚本

如何简单的得到app启动时间

自从4.4发布以来,系统里多了ActivityTaskManager日志

1
ActivityTaskManager: Displayed com.xxx/.MainActivity: +1s290ms

这个系统日志为点击app,到首个activity绘制第一帧的时间

这个时间并不是app可以提供给用户用的时间,它只是到第一帧的时间,如果你想得到整个activity加载完成,可以在合适的位置调用Activity.reportFullyDrawn())给系统,系统会输出以下日志

1
I/ActivityTaskManager: Fully drawn com.xxx/.MainActivity: +2s777ms

如何稳定的得到测试结果

使用adb命令启动activity,使用-W参数,等待app启动完成

因为android启动机制,热启动不能完全反应,用冷启动最好。

so,启动前,应杀掉进程,最好再等待1-2秒钟

输入命令

adb shell am start-activity -W -n com.xxx/.MainActivity

会得到以下日志

1
2
3
4
5
6
7
Starting: Intent { cmp=com.xxx/.MainActivity }
Status: ok
LaunchState: COLD
Activity: com.xxx/.MainActivity
TotalTime: xxx
WaitTime: xxx
Complete

那么编写脚本执行N次,再求平均值就可以得到稳定的启动时长了。

最终大概的脚本

1
2
3
4
5
6
7
8
9
10
allTime=0
for i in `seq 1 $1`
do
adb shell am force-stop $pkg
sleep 1
testc=`adb shell am start-activity -W -n $intentName | grep "TotalTime" | cut -d ' ' -f 2`
allTime=$((10#${testc}+$allTime))
echo "第${i}次: $testc"
done
echo "平均时长$((allTime/$1))"

参数解释

grep 取出需要的字符串

cut 相当于java中的split

-n 使用intentName的方式打开activity

其实am命令里有自动运行多少次的参数,-R 100次数,就可以自动运行app100次,但是这种方式在两次运行之间,没有间隔时间,可能造成cup运行状态不稳定,所以还是用shell的do while方式,中间加上sleep命令

下面是不使用shell的单纯命令

1
adb shell am start-activity -S -W -R 100 -n com.xxx/.MainActivity | grep "TotalTime" | cut -d ' ' -f 2

让cup处于更加平衡的状态测试启动时长,得到一致性更好的结果

androidX基础库提供了锁定cup频率的方法

在工程build文件中加入以下依赖

1
classpath "androidx.benchmark:benchmark-gradle-plugin:1.0.0"

然后应用该插件

1
apply plugin: androidx.benchmark

在命令行中执行

1
./gradlew lockClocks

锁定cup频率

得到以下日志

1
2
Locked CPUs 4,5,6,7 to 1267200 / 2457600 KHz
Disabled CPUs 0,1,2,3

再次运行启动测试脚本,测试app的启动时长。这时可能得到的结果会比刚刚更慢。这是因为,lockClocks使cup保持在一个稳定的性能来执行。而不是因外部因素(电池,功耗等等)而处于高性能的运行环境。

然后使用

1
./gradlew unlockClocks

解锁cup,重启设备就可以了。

最终执行效果

1
2
3
4
5
6
7
➜  Dev git:(master) ✗ ./testlaunchtime.sh 3
开始测试启动时长
正在启动【xxx】app,启动总次数3次
第1次: 3609
第2次: 3534
第3次: 3512
平均时长3551