GT源码:https://github.com/TencentOpen/GT

一.流畅度模块的代码结构

流畅度插件总共就几个类,其实处理方式也比较简单粗暴,就是通过Choreographer输出的log信息获取跳帧数据。SMActivity.java为插件的入口类,你可以通过预设环境操作来实现log打印操作,然后通过SMLogService.java过滤出当前进程的丢帧值,最后由SMServiceHelper.java来进行数据处理。流畅度值为60减去1s内的跳帧数。

二.流畅度测试

1.简要流程

  • 执行setprop debug.choreographer.skipwarning 1
  • 执行getprop debug.choreographer.skipwarning判断,为1则可以进行测试
  • 执行adb logcat -v time -s Choreographer:I *:S
  • 过滤获取当前pid丢帧值
  • 数据处理得到sm值

2.代码流程

  • 执行setprop debug.choreographer.skipwarning 1

    View.OnClickListener button_write_property = new View.OnClickListener() {
    
            @Override
    public void onClick(View v) {
    String cmd = "setprop debug.choreographer.skipwarning 1";
    ProcessBuilder execBuilder = new ProcessBuilder("su", "-c", cmd);
    execBuilder.redirectErrorStream(true);
    try {
    execBuilder.start();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    };
  • 执行getprop debug.choreographer.skipwarning判断,为1则可以进行测试

    View.OnClickListener button_check_status = new View.OnClickListener() {
    
            @Override
    public void onClick(View v) {
    String cmd = "getprop debug.choreographer.skipwarning";
    ProcessBuilder execBuilder = new ProcessBuilder("sh", "-c", cmd);
    execBuilder.redirectErrorStream(true);
    try {
    TextView textview = (TextView) findViewById(R.id.textviewInformation);
    Process p = execBuilder.start();
    InputStream is = p.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    Boolean flag = false;
    String line;
    while ((line = br.readLine()) != null) {
    if (line.compareTo("1") == 0) {
    flag = true;
    break;
    }
    } if (flag) {
    textview.setText("OK");
    } else {
    textview.setText("NOT OK");
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    };
  • 执行adb logcat -v time -s Choreographer:I *:S
  • 过滤获取当前pid丢帧值

    protected void onHandleIntent(Intent intent) {
    try { String str = intent.getStringExtra("pid");
    int pid = Integer.parseInt(str); List<String> args = new ArrayList<String>(Arrays.asList("logcat", "-v", "time", "Choreographer:I", "*:S")); dumpLogcatProcess = RuntimeHelper.exec(args);
    reader = new BufferedReader(new InputStreamReader(dumpLogcatProcess.getInputStream()), 8192); String line; while ((line = reader.readLine()) != null && !killed) { // filter "The application may be doing too much work on its main thread."
    if (!line.contains("uch work on its main t")) {
    continue;
    }
    int pID = LogLine.newLogLine(line, false).getProcessId();
    if (pID != pid){
    continue;
    } line = line.substring(50, line.length() - 71);
    Integer value = Integer.parseInt(line.trim()); SMServiceHelper.getInstance().dataQueue.offer(value);
    }
    } catch (IOException e) {
    Log.e(TAG, e.toString() + "unexpected exception");
    } finally {
    killProcess();
    }
    }
     
  • 数据处理得到sm值

    腾讯这边的处理方案是:当丢帧<60时,流畅度SM =60-frame; 当丢帧frame>60时,流畅度SM = 60-frame%60。不过这种处理方式是有问题的。在这里要先说下流畅度计算的原理:

   VSync机制可以通过其Loop来了解当前App最高绘制能力,固定每隔16.6ms执行一次,这样最高的刷新的帧率就控制在60FPS以内,Choreographer日志可以打印当前丢帧数,因此通过计算,得到当前APP的流畅度。

而计算这样来计算可能会更加准确:

SM= 60-丢帧frame/每两行同一线程的丢帧时间差(单位:s),如果只关心UI线程,那就只需要统计UI线程即可。

  • while (true) {
    if (pause) {
    break;
    }
    int x = count.getAndSet(0);
    // 卡顿大于60时,要将之前几次SM计数做修正
    if (x > 60) {
    int n = x / 60;
    int v = x % 60;
    TagTimeEntry tte = OpPerfBridge.getProfilerData(key);
    int len = tte.getRecordSize();
    // 补偿参数
    int p = n;
    //Math.min(len, n);
    /*
    * n > len是刚启动测试的情况,日志中的亡灵作祟,这种情况不做补偿;
    * 并且本次也记为60。本逻辑在两次测试间会清理数据的情况生效。
    */
    if (n > len) {
    globalClient.setOutPara(key, 60);
    // globalClient.setOutPara(SFKey, 0);
    } else {
    for (int i = 0; i < p; i++) {
    TimeEntry te = tte.getRecord(len - 1 - i);
    te.reduce = 0;
    }
    globalClient.setOutPara(key, v);
    // globalClient.setOutPara(SFKey, 60 - v);
    }
    } else {
    int sm = 60 - x;
    globalClient.setOutPara(key, sm);
    // globalClient.setOutPara(SFKey, x);
    }

腾讯GT的流畅度测试方案研究的更多相关文章

  1. Android流畅度测试

    Android流畅度测试 测试方法一:系统自带-开发者模式 测试方法二:FPS Meter测试安卓帧数 H5页面加载速度:window.performance.timing 测试方法一:系统自带-开发 ...

  2. app流畅度测试--使用手机自带功能

    1.进入开发者选项,在“监控”选项卡找到“GPU呈现模式分析”的选项 2.开启后,即可以条形图和线形图的方式显示系统的界面相应速度 3.那么要如何根据曲线判断系统是否流畅呢?实际上这个曲线表达的是GP ...

  3. app流畅度测试--使用SM

    通过测量应用的帧率FPS并不能准确评价App的流畅度,FPS较低并不能代表当前App在UI上界面不流畅,而1s内VSync这个Loop运行了多少次更加能说明当前App的流畅程度. 那么我们可以直接在A ...

  4. app流畅度测试--使用FPS Meter

    1.FFPS Meter是一款非常实用的小软件,能够用数字实时显示安卓界面的每秒帧数,非常直观.此外,FPS Meter还可以显示最大帧数.最小帧数以及平均帧数,用来评价安卓流畅度极具价值.由于涉及到 ...

  5. Android App性能评测分析-流畅度篇

    1.前言 在手机App竞争越来越激烈的今天,Android App的各项性能特别是流畅度不如IOS,安卓基于java虚拟机运行,触控响应的延迟和卡顿比IOS系统严重得多.一些下拉上滑.双指缩放快速打字 ...

  6. iOS开发之多种Cell高度自适应实现方案的UI流畅度分析

    本篇博客的主题是关于UI操作流畅度优化的一篇博客,我们以TableView中填充多个根据内容自适应高度的Cell来作为本篇博客的使用场景.当然Cell高度的自适应网上的解决方案是铺天盖地呢,今天我们的 ...

  7. 转:iOS开发之多种Cell高度自适应实现方案的UI流畅度分析

    本篇博客的主题是关于UI操作流畅度优化的一篇博客,我们以TableView中填充多个根据内容自适应高度的Cell来作为本篇博客的使用场景.当然Cell高度的自适应网上的解决方案是铺天盖地呢,今天我们的 ...

  8. 专项测试实战 | 如何测试 App 流畅度(基于 FPS 和丢帧率)

    本文为霍格沃兹测试学院学员学习笔记. FPS 和丢帧率可以在一定程度上作为 APP 流畅度的一项衡量标准,本文介绍利用 adb shell dumpsys gfxinfo 命令获取软件渲染加载过程的数 ...

  9. 腾讯的一个移动端测试小工具GT

    上周末参加了Ministar北京的测试聚会.腾讯的MIG专项测试组的组长给大家介绍了他们最近开发出来的手机测试工具GT. 下面是GT的官方说明: GT(随身调)是APP的随身调测平台,它是直接运行在手 ...

随机推荐

  1. 如何部署Zabbix服务端

    部署环境 RHEL 6.7 Zabbix-server 2.2.14 安装zabbix官方源 # wget http://repo.zabbix.com/zabbix/2.2/rhel/6/x86_6 ...

  2. Cesium原理篇:Material

    Shader 首先,在本文开始前,我们先普及一下材质的概念,这里推荐材质,普及材质的内容都是截取自该网站,我觉得他写的已经够好了.在开始普及概念前,推荐一首我此刻想到的歌<光---陈粒>. ...

  3. WebApi跨域问题

    1.通过Nuget下载CORS安装包 2.在WebApiConfig.cs文件中注册CORS 3.在全局文件启用CORS支持 4.在控制器上添加头

  4. .Net语言 APP开发平台——Smobiler学习日志:如何快速实现快递信息流的效果

    最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 样式一 一.目标样式 我们要实现上图中的效果,需要如下的操作: 1.从工具栏上的&qu ...

  5. sql 补齐字段位数

    select top 100 lmdte, right(replicate('0',6)+ltrim(lmtme),6) from smtpdsum where lmdte <> 0

  6. PHP变量

    变量的声明 PHP变量声明必须是$(美元符号)+变量名进行命名,同时在=(赋值操作符)后进行赋值 声明后的变量不是仅可以在一个<?php 这里是php代码 ?>使用,它还可以在当前页面所有 ...

  7. 开源物联网框架ServerSuperIO(SSIO),项目中实践应用介绍

    一.项目背景 我们是传统行业,但是我们有一颗不传统的心.企业用户遍布国内和国外,面对行业,要建设行业级的(大)数据平台.一提到大数据平台,大家往往想到Hadoop.Spark.Nosql.分布式等等, ...

  8. 千万pv大型web系统架构,学习从点滴开始

     架构,刚开始的解释是我从知乎上看到的.什么是架构?有人讲, 说架构并不是一 个很 悬 乎的 东西 , 实际 上就是一个架子 , 放一些 业务 和算法,跟我们的生活中的晾衣架很像.更抽象一点,说架构其 ...

  9. mysql主从之slave-skip-errors和sql_slave_skip_counter

    一般来说,为了保险起见,在主从库维护中,有时候需要跳过某个无法执行的命令,需要在slave处于stop状态下,执行 set global sql_slave_skip_counter=1以跳过命令.但 ...

  10. ++a和a++的区别

    另: short s = 4; s = s + 1; // 编译不通过.因为编译器无法判断等号右边的运算结果是否依然在等号左边的short类型范围内,容易丢失精度. s += 1; // 编译通过.+ ...