我爱编程

采用观察者模式收集Android性能数据收集

2018-04-16  本文已影响0人  穿靴子跳迪斯kou的猫

观察者模式
      观察者模式主要用来在一对多依赖关系中,通知被观察者同步状态或数据,android执行monkey期间收集性能数据,当数据返回时,我们可以采用观察者模式来通知数据收集器,更新数据,经典观察者模式结构图引用观察者模式

图片来源于网络.png

基本性能指标
      获取android端的性能数据,可以通过以下命令,其中主要依赖于top和dumpsys命令,具体如下:
CPU
cpu使用情况可以通过top/dumpsys命令来获取,如

adb shell top -m 100 -n 1 -s cpu | grep 包名;
adb shell dumpsys cpuinfo |grep 包名。

内存
      查看内存使用情况使用命令

 adb shell dumpsys meminfo 包名

流量
      查看流量使用情况使用命令

adb shell cat /proc/net/xt_qtaguid/stats | grep uid

其中uid 可以通过

dumpsys package 包名| grep userId=

掉帧率
      页面流畅度,我们不能通过fps来判断页面是否卡顿,但是我们可以通过每一帧的加载时间,来判断该帧是否加载超时,按照标准识动画的频率大约是每秒连续加载60帧,人眼才不会感觉到卡顿,那么平均每一帧的加载时间不得超过1s/60帧,即16.6ms,那么每一帧加载的四个阶段(draw,prepare,process,executor)时间之和不能超过16.6ms,超时现象被称为掉帧,掉帧数越大,表明页面卡顿越严重。我们先通过“dumpsys gfxinfo 包名” 获取帧加载情况,再计算每一帧的加载总时间,统计掉帧数,计算出掉帧率。

执行monkey测试期间收集性能数据
在启动monkey测试前,初始化androidPerformanceData参数并传递给执行器。

@Override
public void coreTesting(BaseTestData baseTestData) throws Exception {
    MonkeyTestRunner runner = new MonkeyTestRunner();
    //执行monkey测试时,收集性能数据
    runner.startMonkeyTest(androidPerformanceData, sn, app, monkeyTime, 0, 0, 0, 0, 0, 0); 
baseTestData.setPerformanceData(androidPerformanceData);
}

在执行monkey线程中起性能收集任务androidPerformanceRunner,示例如下

 try {
                        if (androidPerformanceData != null){
                            //开始收集性能数据
                            androidPerformanceRunner = new AndroidPerformanceRunner(device, pkgName, androidPerformanceData);
                            androidPerformanceRunner.start();
                        }
                        device.executeShellCommand(command, receiver, 60000);
                        result = true;
                    } catch (ShellCommandUnresponsiveException mttor) {
                        result = true;
                    } catch (Exception ex) {
                        result = false;
                    } finally {
                        if (androidPerformanceData != null ){
                            //结束收集性能数据
                            if (androidPerformanceRunner != null){
                                androidPerformanceRunner.stop();
                            }
                        }
                    }

采用观察者模式同步性能数据
      在AndroidPerformanceRunner提供方法getMemoryInfo、getxxinfo获取不同的性能数据,以获取内存为例,如下:

          JSONObject memInfo = getMemoryInfo(pkgName, device);
            if (memInfo == null) {
                memInfo = new JSONObject();
                memInfo.put("total_mem", 0);
                memInfo.put("app_mem", 0);
            }
            memInfo.put("time", time);
 performanceData.getJSONArray("mem_info").add(memInfo);

其中getMemoryInfo方法中使用MemInfoService类实例,MemInfoService类继承Observable类,并提供方法executeCmd4GetMemInfo执行cmd命令收集数据,数据收集完毕后,通过Observable的notifyObservers方法通知观察者更新数据。

 public void executeCmd4GetMemInfo() {
    String cmd = "cat /proc/meminfo | grep MemTotal:";
    try {
        device.executeShellCommand(cmd, totalMemInfoReceiver);
    } catch (TimeoutException e) {
        e.printStackTrace();
    } catch (AdbCommandRejectedException e) {
        e.printStackTrace();
    } catch (ShellCommandUnresponsiveException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    Integer memInfo = getTotalMemInfo();
    if (memInfo > 0) {
        setChanged();
        notifyObservers(memInfo);
    }

在notifyObservers方法中,采用同步锁更新数据

 synchronized (this) {
        if (!changed)
            return;
        arrLocal = obs.toArray();
        clearChanged();
    }
    for (int i = arrLocal.length-1; i>=0; i--)
        ((Observer)arrLocal[i]).update(this, arg);
}

数据处理
      收集完数据后,采用json格式拼装性能数据,并上报至报告中心。

private JSONObject handlePerformanceData(BaseTestData baseTestData){
        JSONObject data = new JSONObject();
        JSONObject performanceInfo = baseTestData.getPerformanceData();
        if (performanceInfo != null){
            data.put("mem_info", getMemInfo(performanceInfo.getJSONArray("mem_info")));
            data.put("cpu_info", getCPUInfo(performanceInfo.getJSONArray("cpu_info")));
            data.put("fps_info", getFPSInfo(performanceInfo.getJSONArray("fps_info")));
            data.put("traffic_info", getTrafficInfo(performanceInfo.getJSONArray("traffic_info")));
        }
        return data;
}

至此,性能数据收集完毕。

上一篇下一篇

猜你喜欢

热点阅读