使用 adb shell 抓取 Android 性能数据

前段时间在看Android客户端性能测试,处于兴趣写了个性能数据抓取的插件,可以抓取的数据有app启动时间、cpu、pss、流量上下行、流畅度等。

关于内存要说一下为什么只抓取pss,因为没有root的情况下无法获取到uss,pss是最有参考价值的(进程占用内存+按比例分配共享库占用的内存)

流量抓取方式也略有不同,前一种方法获取tcp流量,而且在有的设备上无法获取到数据,无法做到普适性:
  • 改之前:
    shell
    adb -s #udid# shell cat /proc/uid_stat/#uid#/tcp_rcv
    adb -s #udid# shell cat /proc/uid_stat/#uid#/tcp_snd
  • 改之后:
    shell
    adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{tx_bytes+=$6}END{print '$(date +%Y%m%d%H%M%S)',tx_bytes}
    adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{tx_bytes+=$8}END{print '$(date +%Y%m%d%H%M%S)',tx_bytes}

流畅度阈值的界定:按官网的建议每秒小于60帧就能感觉到不流畅,也就是说每帧的阈值=1000/60 =16ms

app启动时间获取原理:

  • 获取logcat日志:
    shell
    adb -s $1 shell logcat -v time -b events > output/$1/latest/logcat_$1.txt &
  • 根据起始关键字和结束关键字过滤时间戳:
    java
    handlLogcat = new Thread(new CmdThread("./shell/appLanchTimeClient.sh " + udid + " " + beginKeywords + " " + endKeywords), "handlLogcat_" + udid);

计算时间差:

java
startTime = CmdInvoke.run("tail -n 1 output/" + udid + "/latest/start_" + udid + ".txt |awk '{print $2}'");
endTime = CmdInvoke.run("tail -n 1 output/" + udid + "/latest/end_" + udid + ".txt |awk '{print $2}'");
lantchTime = DateUtil.getDifTwoTime(DateUtil.parsehmsS(endTime), DateUtil.parsehmsS(startTime), "S");

获取设备的一些临界值

shell
heapgrowthlimit=`adb -s $udid shell getprop dalvik.vm.heapgrowthlimit
heapstartsize=`adb -s $udid shell getprop dalvik.vm.heapstartsize`
heapsize=`adb -s $udid shell getprop dalvik.vm.heapsize`
echo "#单个应用程序最大内存限制" > output/$udid/devMemLimit.txt
echo "heapgrowthlimit="$heapgrowthlimit >> output/$udid/devMemLimit.txt
echo "#单个java虚拟机最大的内存限制" >> output/$udid/devMemLimit.txt
echo "heapsize="$heapsize >> output/$udid/devMemLimit.txt
echo "#每帧刷新耗时阈值(ms)" >> output/$udid/devMemLimit.txt
60FPS<==>每帧<=16msFPS=1000/(Draw+Process+Execute)
打开android手机 设置->开发者选项->GPU呈现模式分析
echo "gfxinfo=16.00" >> output/$udid/devMemLimit.txt

命令模板

public class CmdTemplate {
public static String PID = “adb -s #udid# shell dumpsys meminfo packageName|grep pid|awk ‘{print $5}’”;
public static String UID = “adb -s #udid# shell dumpsys package #packageName#|grep packageSetting|cut -d \”/\” -f2|cut -d \”}\” -f1”;

    /**实时抓取**/
// TIMESTAMP(yyyymmddHHMMSS) CPU(%) PID/PACKAGE
public static String CPU_USAGE = "adb -s #udid# shell dumpsys cpuinfo|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$2}'|grep #pid#";

// TIMESTAMP(yyyymmddHHMMSS) PSS(KB) PACKAGE
public static String PSS = "adb -s #udid# shell dumpsys meminfo|awk '/process:/,/adjustment:/{if(i>1)print x;x=$0;i++}'|grep #filter#|grep #pid#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$3}'";

// TIMESTAMP(yyyymmddHHMMSS) RX_BYTES(BYTE)
public static String RX_BYTES = "adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{rx_bytes+=$6}END{print '$(date +%Y%m%d%H%M%S)',rx_bytes}'";

// TIMESTAMP(yyyymmddHHMMSS) TX_BYTES(BYTE)
public static String TX_BYTES = "adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{tx_bytes+=$8}END{print '$(date +%Y%m%d%H%M%S)',tx_bytes}'";

    /**异步抓取**/
// TIMESTAMP(yyyymmddHHMMSS) PID VSS(KB) RSS(KB) PACKAGE
public static String SAVE_TOP_INFO = "adb -s #udid# shell top -n 1 -d 0|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$6,$7,$10}' >> output/#udid#/latest/top_#udid#.txt";

// TIMESTAMP(yyyymmddHHMMSS) CPU(%) PID/PACKAGE
public static String SAVE_CPU_INFO = "adb -s #udid# shell dumpsys cpuinfo|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$2}' >> output/#udid#/latest/cpu_#udid#.txt";

// TIMESTAMP(yyyymmddHHMMSS) PSS(KB) PACKAGE
public static String SAVE_PSS_INFO = "adb -s #udid# shell dumpsys meminfo|awk '/process:/,/adjustment:/{if(i>1)print x;x=$0;i++}'|grep #filter#|awk '{print '$(date +%Y%m%d%H%M%S)',$1,$3}' >> output/#udid#/latest/pss_#udid#.txt";

// TIMESTAMP(yyyymmddHHMMSS) RX_BYTES(BYTE) TX_BYTES(BYTE)
public static String SAVE_TRAFFIC_INFO = "adb -s #udid# shell cat /proc/net/xt_qtaguid/stats|grep #uid#|awk '{rx_bytes+=$6}{tx_bytes+=$8}END{print '$(date +%Y%m%d%H%M%S)',rx_bytes,tx_bytes}' >> output/#udid#/latest/traffic_#udid#.txt";

// Draw(MS) Process(MS) Execute(MS)
public static String SAVE_GFX_INFO = "adb -s #udid# shell dumpsys gfxinfo #packageName#|awk '/Execute/,/hierarchy/{if(i>1)print x;x=$0;i++}'|sed /^[[:space:]]*$/d|awk '{if(length($0)==16)print $1,$2,$3}' >> output/#udid#/latest/gfxinfo_#udid#.txt";

}

支持实时抓取数据和异步抓取数据,异步抓取每个抓取类型会分配一个线程,异步抓取的数据以文件形式持久化到本地。

pss抓取内容
20151201163741 41414 com.yzt
20151201163741 22044 com.yzt:remote
20151201163741 21048 comyzt:pushservice
20151201163741 19309 com.yzt:push
20151201163747 48010 com.yzt
20151201163747 22047 com.yzt:remote
20151201163747 21132 com.yzt:pushservice
20151201163747 19333 com.yzt:push

cpu抓取内容
20151201163739 0.8% 9819/com.yzt:remote:
20151201163739 0% 9699/com.yzt:
20151201163743 5.2% 9699/com.yzt:
20151201163743 1% 9819/com.yzt:remote:
20151201163743 0% 14177/com.yzt:pushservice:

流量抓取内容
20151201163740 1119317 1313028
20151201163743 1119317 1313028
20151201163746 1429836 1328958
20151201163749 1509060 1337427
20151201163752 2525902 1381403

每帧耗时抓取内容
1.30 1.25 0.53
0.63 0.62 1.64
0.24 0.51 0.44
0.25 1.76 0.40
0.25 1.55 0.43
0.25 0.53 0.37
0.49 1.51 2.12
0.45 0.67 0.27
0.43 0.71 2.83
0.43 0.76 3.04

报表展示:

使用 adb shell 抓取 Android 性能数据_第1张图片

你可能感兴趣的:(Appium,性能测试)