Android UI卡顿分析

Android渲染刷新机制

渲染操作通常依赖于两个核心组件:CPU与GPU。CPU负责包括Measure,Layout等计算操作,GPU负责Rasterization(栅格化)操作(所谓栅格化就是将矢量图形转换为位图的过程,手机上显示是按照一个个像素来显示的,栅格化再普通一些的说法就是将一个Button,TextView等组件拆分到一个个像素上去显示)。

Android系统每隔16ms发出VSYNC信号(垂直刷新/绘制),完触发对UI进行渲染,那么整个过程如果保证在16ms以内就能达到一个流畅的画面。如果在16ms内没有把这一帧的任务执行毕,就会发生丢帧的现象(大家在察觉到APP卡顿的时候,可以看看logcat控制台,会有drop frames类似的警告)。

GPU会获取图形数据进行渲染,然后硬件负责把渲染后的内容呈现到屏幕上,他们两者不停的进行协作。

不幸的是,刷新频率和帧率并不是总能够保持相同的节奏。如果发生帧率与刷新频率不一致的情况,就会容易出现Tearing的现象(画面上下两部分显示内容发生断裂,来自不同的两帧数据发生重叠)。

VSYNC:有两个概念
1)Refresh Rate:屏幕在一秒时间内刷新屏幕的次数----有硬件的参数决定,比如60HZ.
2)Frame Rate:GPU在一秒内绘制操作的帧数,比如:60fps。
16ms意味着1000/60hz,即60HZ的刷新屏幕,也意味着60fps的帧率。
这是因为人眼与大脑之间的协作无法感知超过60fps的画面更新。
12fps大概类似手动快速翻动书籍的帧率,这明显是可以感知到不够顺滑的。
24fps使得人眼感知的是连续线性的运动,这其实是归功于运动模糊的效果。
24fps是电影胶圈通常使用的帧率,因为这个帧率已经足够支撑大部分电影画面需要表达的内容,同时能够最大的减少费用支出。
但是低于30fps是无法顺畅表现绚丽的画面内容的,
需要用到60fps来达到想要的效果。

UI卡顿的根本原因

Android每隔16ms就会绘制一次Activity,通过上述的结论我们知道,如果由于一些原因导致了我们的逻辑、CPU耗时、GPU耗时大于16ms,UI就无法完成一次绘制,那么就会造成卡顿。简单的一句话就是:卡主线程了。

一、外部因素引起的(以View为区分)

  1. 内存抖动的问题
  2. 方法太耗时了(CPU占用)

内存抖动现象

Android有自动管理内存的机制,但是对内存的不恰当使用仍然容易引起严重的性能问题。在同一帧里面创建过多的对象是件需要特别引起注意的事情,在同一帧里创建大量对象可能引起GC的不停操作,执行GC操作的时候,所有线程的任何操作都会需要暂停,直到GC操作完成。大量不停的GC操作则会显著占用帧间隔时间。

  • 一是内存抖动,所谓内存抖动就是短时间产生大量对象又在短时间内马上释放。
  • 二是短时间产生大量对象超出阈值,内存不够,同样会触发GC操作。

观察内存抖动借助android studio中的工具,3.0以前android monitor,3.0以后被替换为android Profiler。

如果工具里面查看到短时间发生了多次内存的涨跌,这意味着很有可能发生了内存抖动,如图:

为了避免发生内存抖动,我们需要避免在for循环里面分配对象占用内存,需要尝试把对象的创建移到循环体之外。

自定义View中的onDraw方法也需要引起注意,每次屏幕发生绘制以及动画执行过程中,onDraw方法都会被调用到,避免在onDraw方法里面执行复杂的操作,避免创建对象。

对于那些无法避免需要创建对象的情况,我们可以考虑对象池模型,通过对象池来解决频繁创建与销毁的问题,但是这里需要注意结束使用之后,需要手动释放对象池中的对象。

方法耗时(CPU占用)的问题

以斐波那契数列为例进行模拟,粗略地通过Profiler工具可以看到CPU的占用突然提高了,但是内存的使用几乎不动。

解决办法

  1. 修改方法(算法),使得方法不耗时。
  2. 放到子线程中,例如网络访问、大文件操作等,防止ANR。

二、View本身的卡顿

后面做进一步分析与优化,见https://blog.csdn.net/u013773608/article/details/101521813

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值