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. [Android]在Dagger 2中使用RxJava来进行异步注入(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客: # 在Dagger 2中使用RxJava来进行异步注入 > 原文: 几星期前我写了一篇关于在Dagger 2中使用*Producers*进行 ...

  2. The Road To Hadoop(网盘系统的实现)

    因为毕业设计的原因,得从零开始学习hadoop.虽然接触Hadoop也有一段时间了,但是没有一个完整的时间段去学习,在公司实习的同时,只能利用零零碎碎的时间学习,今天完成了第一个版本的基于Hadoop ...

  3. 跨域之同源策略 Same-origin policy

    同源策略是浏览器中最基本的隔离潜在恶意文件的安全策略,他限制了来自不同源(origin)的文档或脚本之间的相互作用. 何谓同源 在跨域之URL中介绍过一个URL的标准格式如下: 协议类型://服务器地 ...

  4. 浅谈css的伪元素::after和::before

    css中的::after和::before已经被大量地使用在我们日常开发中了,使用他们可以使我们的文档结构更加简洁.但是很多人对::after和::before仍不是特别了解,究竟他们是做什么的?如何 ...

  5. Python爬虫小白入门(二)requests库

    一.前言 为什么要先说Requests库呢,因为这是个功能很强大的网络请求库,可以实现跟浏览器一样发送各种HTTP请求来获取网站的数据.网络上的模块.库.包指的都是同一种东西,所以后文中可能会在不同地 ...

  6. [Quartz笔记]玩转定时调度

    简介 Quartz是什么? Quartz是一个特性丰富的.开源的作业调度框架.它可以集成到任何Java应用. 使用它,你可以非常轻松的实现定时任务的调度执行. Quartz的应用场景 场景1:提醒和告 ...

  7. C#生成带logo的二维码

    带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码. 生成的二维码效果如下: 下面直接贴出二维码生成类   QRCode ...

  8. DateHelper.cs日期时间操作辅助类C#

    //==================================================================== //** Copyright © classbao.com ...

  9. Redis初识

    安装与使用 Redis-x64-3.2.100:服务端 + 客户端 redis-3.2.5:源代码 Redis Desktop Manager - v0.8.8:客户端(基于Qt5的跨平台Redis桌 ...

  10. intellij idea 15 修改基础配置加载路径

    一.概述 intellij idea 15 默认配置的启动加载路径是"C:\Users\Administrator.IntelliJIdea15",这样会导致占用C盘的空间越来越多 ...