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. MUI开发APP,scroll组件,运用到区域滚动

    最近在开发APP的过程中,遇到一个问题,就是内容有一个固定的头部和底部.         头部就是我们常用的header了,底部的话,就放置一个button,用来提交页面数据或者进入下一个页面等,效果 ...

  2. 压缩SWF文件大小!减少40%体积!

     使用FlashBuild作为IDE的痛苦是显著的!如果开发的项目比较大,那么卡顿.崩溃.白屏是常事,使用别的IDE开发如Sublime.FlashDevelop.IDEA等,然后再用mxmlc编译出 ...

  3. ubuntu 14.04LTS 环境下配置NFS服务

    简言之,NFS(Network FileSystem,网络文件系统)用于在不同机器,不同操作系统之间通过网络互相分享各自的文件.NFS设计之初就是为了在不同的系统间使用,所以它的通讯协议设计与主机及操 ...

  4. 翻译:使用 ASP.NET MVC 4, EF, Knockoutjs and Bootstrap 设计和开发站点 - 4 - 验证

    验证: 快要完成我们程序的界面部分了.剩下的事情就是在用户点击 "保存" 的时候管理验证问题了.验证是主要需求,今天就是最无知的应用也不会忽视它.通过正确的验证,用户可以知道应该输 ...

  5. C#开发微信门户及应用(25)-微信企业号的客户端管理功能

    我们知道,微信公众号和企业号都提供了一个官方的Web后台,方便我们对微信账号的配置,以及相关数据的管理功能,对于微信企业号来说,有通讯录中的组织架构管理.标签管理.人员管理.以及消息的发送等功能,其中 ...

  6. bzoj2693--莫比乌斯反演+积性函数线性筛

    推导: 设d=gcd(i,j) 利用莫比乌斯函数的性质 令sum(x,y)=(x*(x+1)/2)*(y*(y+1)/2) 令T=d*t 设f(T)= T可以分块.又由于μ是积性函数,积性函数的约束和 ...

  7. EC笔记:第三部分:14、在资源管理类中小心Copying行为

    场景 上一节实现了智能指针,其中的拷贝构造函数和赋值运算符是通过增加/减少指针的引用计数来操作的.但是如果是管理一个独占资源呢?我们希望在一个资源使用时被锁定,在使用完毕后被释放. #include ...

  8. JavaWeb_day02_登录校验_查询所有员工信息_DeBug

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! WEB_day02 servlet 协议转对象 服务器 ...

  9. FFmpeg滤镜实现区域视频增强 及 D3D实现视频播放区的拉大缩小

    1.区域视频增强 FFmpeg滤镜功能十分强大,用滤镜可以实现视频的区域增强功能. 用eq滤镜就可以实现亮度.对比度.饱和度等的常用视频增强功能. 推荐两篇写得不错的博文: (1)ffmpeg综合应用 ...

  10. python中的TypeError错误解决办法

    新手在学习python时候,会遇到很多的坑,下面来具体说说其中一个. 在使用python编写面向对象的程序时,新手可能遇到TypeError: this constructor takes no ar ...