利用Traceview 解决页面卡顿问题

    背景:我在做一个可以滚动的页面的时候插入一个可以播放gif动画的控件,结果发现,如果这个动画在播放的时候,滑动页面会发现卡顿。开始以为是硬件加速问题......最后通过traceview工具发现真正的原因。

    android手机开发模式中有一个监控选项下有个属性是gpu显示配置文件,在里面选中以条的形式显示于屏幕。开启之后会发现页面会出现很多的竖线。这个就表示了渲染每帧需要多少时间。按照规则,我们必须要使之小于16ms,

 不然就会出现卡顿(失帧)。最下面有一条绿色横线,这个就是16ms分割线,超过这部分的都是大于16ms的。

 

    1. 蓝色部分:表示绘制时间或者在Java层创建和更新display list的时间。在一个View 实际被渲染前,它需要先转换为GPU能识别的格式。简单来说可能就是几个绘制命令,复杂一点,我们可能在嵌入了一条从canvas获取的自定义路径。这一步完成之后,输出结果就会被系统作为display list缓存起来。 这部分部分记录了这一帧对所有需要更新的view完成这两步花费的时间。当它很高的时候,说明有很多view突然无效(invalidate)了,或者是有几个自定义view在onDraw函数中做了特别复杂的绘制逻辑。

       

    2. 红色部分:代表执行时间,也就是Android 2D渲染引擎(OpenGL)执行display list的时间。为了将变化绘制在屏幕上,Android需要使用OpenGL ES API来绘制这些display list信息,OpenGL最终将数据传给了GPU,然后GPU渲染到屏幕上。View越复杂,OpenGL绘制所需要的命令也越复杂。如果红色这一段比较高,复杂的view都可能是罪魁祸首。还有值得注意的是比较大的峰值,这说明有些view重复提交了,也就是绘制了多次,而它们可能并不需要重绘。

       

    3. 橙色部分:代表处理时间,更进一步,就是CPU告诉GPU渲染已经完成的时间。这部分是阻塞的,CPU会等待GPU知道确认收到了命令,如果这里比较高,说明GPU做的任务太多了,通常是由于很多复杂的view绘制从而需要过多的OpenGL渲染命令去处理。

注意:使顺利在60帧,每帧必须小于16毫秒完成。

关于Execute:如果执行耗费了过长的时间,这意味着你是跑在前面的图形管线。 android在运行时可以有3个缓冲区.如果你需要另一个应用程序将阻塞直到其中的一个缓冲区释放出来。两个原因会发生这种情况。第一,你的应用在Dalvik中快速绘制但在GPU显示列表时候消耗了大量时间。第二,你的应用程序花了很长的时间来执行第几帧;一旦管线满了他将无法赶上,除非动画完成。

  一般都是蓝色部分时间消耗过长。怎么分析呢?

  利用android studio下面的android-cpu,在页面展示开始和结束的时候分别点击左边按钮一次,会生成一个.trace文件,如果需要时间更加准确的,可以在activity的onCreate()中添加Debug.startMethodTracing(), 而在onStop中添加Debug.stopMethodTracing();拿到这个.trace文件之后,在android sdk tools目录下,把这个.trace直接丢给traceview.bat。它会自动打开一个视图

 接下来,只要选择上方一种颜色跨度最大的分析一下,看看到底是什么方法占用了如此多的时间。

  我发现解决的这个问题是因为在onDraw里面写了个Thread.sleep(40)。sleep都sleep40ms了,能不卡么,改成postDelayed,成功分析解决。

 

posted @ 2016-01-27 17:37  saki_god  阅读(1036)  评论(0编辑  收藏  举报