Android性能测试帧率、卡顿详解及分析使用

卡顿分析

FPS帧率统计评测应用流畅度并不准确

系统获取FPS的原理:手机屏幕显示的内容是通过Android系统的SurfaceFlinger类,把当前系统里所有进程需要显示的信息合成一帧,然后提交到屏幕上显示,FPS就是1秒内SurfaceFlinger提交到屏幕的帧数,SurfaceFlinger目前的启动方式是做为init进程中的一个Service来启动。

App停止操作后,FPS还是在一直变化,这种情况是否会影响到FPS的准确度?
有的时候FPS很低,APP看起来却很流畅,是因为当前界面在1秒内只需要10帧的显示需求,当然不会卡顿,此时FPS只要高于10就可以了,如果屏幕根本没有绘制需求,那FPS的值就是0。

Vsync(垂直同步)指的是显卡的输出帧数和屏幕的垂直刷新率相同。

垂直同步的含义我们可以理解为,使得显卡生成帧的速度和屏幕刷新的速度的保持一致。举例来说,如果屏幕的刷新率为60Hz,那么生成帧的速度就应该被固定在1/60 s。

Android 4.1引入了VSync机制可以通过其Loop来了解当前App最高绘制能力。

Choreographer接收显示系统的时间脉冲(垂直同步信号-VSync信号),在下一个frame渲染时控制执行这些操作,控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作。

Choreographer类的构造方法:

1.初始化FrameHandler。接收处理消息。

2.初始化FrameDisplayEventReceiver。FrameDisplayEventReceiver用来接收垂直同步脉冲,就是VSync信号,VSync信号是一个时间脉冲,一般为60HZ,用来控制系统同步操作,怎么同ChoreoGrapher一起工作的,将在下文介绍。

3.初始化mLastFrameTimeNanos(标记上一个frame的渲染时间)以及mFrameIntervalNanos(帧率,fps,一般手机上为1s/60)。

4.初始化CallbackQueue,callback队列,将在下一帧开始渲染时回调。

FrameHandler

一个简单的handler,处理3个类型的消息。

MSG_DO_FRAME:开始渲染下一帧的操作

MSG_DO_SCHEDULE_VSYNC:请求Vsync信号

MSG_DO_SCHEDULE_CALLBACK:请求执行callback

FrameDisplayEventReceiver

FrameDisplayEventReceiver继承自DisplayEventReceiver接收底层的VSync信号开始处理UI过程。VSync信号由SurfaceFlinger实现并定时发送。FrameDisplayEventReceiver收到信号后,调用onVsync方法组织消息发送到主线程处理。这个消息主要内容就是run方法里面的doFrame了,源码中mTimestampNanos是信号到来的时间参数。

1.PostCallBack,发起添加回调,这个FrameCallBack将在下一帧被渲染时执行。

2.AddToCallBackQueue,将FrameCallBack添加到回调队列里面,等待时机执行回调。每种类型的callback按照设置的执行时间(dueTime)顺序排序分别保存在一个单链表中。

3.判断FrameCallBack设定的执行时间是否在当前时间之后,若是,发送MSG_DO_SCHEDULE_CALLBACK消息到主线程,安排执行doScheduleCallback,安排执行CallBack。否则直接跳到第4步。

4.执行scheduleFrameLocked,安排执行下一帧。

5.判断上一帧是否已经执行,若未执行,当前操作直接结束。若已经执行,根据情况执行以下6、7步。

6.若使用垂直同步信号进行同步,则执行7.否则,直接跳到9。

7.若当前线程是UI线程,则通过执行scheduleVsyncLocked请求垂直同步信号。否则,送MSG_DO_SCHEDULE_VSYNC消息到主线程,安排执行doScheduleVsync,在主线程调用scheduleVsyncLocked。

8.收到垂直同步信号,调用FrameDisplayEventReceiver.onVsync(),发送消息到主线程,请求执行doFrame。

9.执行doFrame,渲染下一帧。

Choreographer中可以实现FrameCallback接口,然后实现里边的doFrame方法,可以获取到帧率等信息,通过Choreographer.getInstance().postFrameCallback(new MyFPSFrameCallback());
把你的回调添加到Choreographer之中,那么在下一个frame被渲染的时候就会回调你的callback,执行你定义的doFrame操作,这时候你就可以获取到这一帧的开始渲染时间并做一些自己想做的事情了。
开源组件Tiny Dancer就是根据这个原理获取每一帧的渲染时间,继而分析实现获取设备的当前帧率的。有兴趣的人可以查看。

private long mLastFrameTimeNanos=0; //实际执行当前frame的时间

private long mFrameIntervalNanos;

public FpsInfo(long lastFrameTimeNanos){

mLastFrameTimeNanos=lastFrameTimeNanos;

mFrameIntervalNanos=(long)(1000000000 / 60.0); // 帧率,也就是渲染一帧的时间,getRefreshRate是刷新率,一般是60

}
@Override

public void doFrame(long frameTimeNanos) { //Vsync信号到来的时间frameTimeNanos

if(mLastFrameTimeNanos==0){

mLastFrameTimeNanos=frameTimeNanos;

}

final long jitterNanos=frameTimeNanos-mLastFrameTimeNanos;

if(jitterNanos>=mFrameIntervalNanos){

final long skippedFrames=jitterNanos/mFrameIntervalNanos;

//Log.i("Testing","Skipped "+skippedFrames+" frames!");

if(skippedFrames>60){ //设定丢帧率 60

Log.i("Testing","Skipped "+skippedFrames+" frames!");

}

}

mLastFrameTimeNanos=frameTimeNanos;

//注册下一帧的回调

Choreographer.getInstance().postFrameCallback(this);

}

尽量避免在执行动画或渲染操作之后在主线程执行操作,在之前或之后都应该尽量避免发送消息到主线程looper。

流畅度衡量指标:

1.帧率FPS

2.丢帧SF(Skipped frame)

3.流畅度SM(SMoothness)。

腾讯bugly对于流畅度及丢帧的链接:http://www.csdn.net/article/2015-06-12/2824949/4

SurfaceFlinger原理及启动篇:http://gityuan.com/2017/02/11/surface_flinger/

优化流程:

1.UI层级嵌套绘制

2.静态代码扫描工具配合

3.Traceview定位主线程卡顿问题

4.Systrace分析

5.Strictmode严苛模式主线程耗时操作

6.Blockcanary非侵入式自动检测卡顿

最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】

 全套资料获取方式:点击下方小卡片自行领取即可

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 Selenium 和 Python 进行 Grome 视频性能测试的代码示例: ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options import time # 设置 Chrome 浏览器的参数 chrome_options = Options() chrome_options.add_argument('--disable-gpu') chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument('--disable-setuid-sandbox') chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-infobars') chrome_options.add_argument('--disable-extensions') chrome_options.add_argument('--disable-popup-blocking') chrome_options.add_argument('--disable-default-apps') chrome_options.add_argument('--disable-translate') chrome_options.add_argument('--disable-background-timer-throttling') chrome_options.add_argument('--disable-renderer-backgrounding') chrome_options.add_argument('--disable-device-discovery-notifications') chrome_options.add_argument('--disable-web-security') chrome_options.add_argument('--allow-running-insecure-content') chrome_options.add_argument('--ignore-certificate-errors') # 创建 Chrome 浏览器实例 driver = webdriver.Chrome(options=chrome_options) # 打开 Grome 视频页面 driver.get('https://www.grome.io/demo') # 等待视频加载完成 time.sleep(10) # 获取视频播放器元素 video_player = driver.find_element_by_tag_name('video') # 获取视频帧率 frame_rate = driver.execute_script('return arguments[0].webkitDecodedFrameCount / arguments[0].duration;', video_player) print('帧率:', frame_rate) # 获取视频卡顿率 stall_events = driver.execute_script('return arguments[0].webkitVideoDecodedByteCount - arguments[0].webkitVideoFrameByteCount;', video_player) stall_rate = stall_events / video_player.duration print('卡顿率:', stall_rate) # 获取视频音画同步率 sync_events = driver.execute_script('return arguments[0].webkitAudioDecodedByteCount - arguments[0].webkitAudioFrameByteCount;', video_player) sync_rate = sync_events / video_player.duration print('音画同步率:', sync_rate) # 获取视频播放延迟 latency = driver.execute_script('return arguments[0].currentTime - arguments[0].webkitPresentationTimestamp;', video_player) print('播放延迟:', latency) # 关闭浏览器 driver.quit() ``` 这段代码可以获取 Grome 视频的帧率卡顿率、音画同步率和播放延迟等性能指标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值