android性能优化——渲染性能

大多数用户感知到的卡顿问题主要源于渲染性能问题,更多的图片动画虽然有助于提升用户体验,但是如果android系统不能及时完成那些复杂UI的渲染操作,就会引起渲染性能问题。
Android系统每16ms发出以此VSYNC信号,用来触发对UI的渲染操作,如果每次都渲染成功,那么就能保证达到60fps的流畅画面所需要的帧率,这就意味着程序的大部分操作都要在16ms内完成。如果某一操作耗费了24ms完成,那么系统在得到VSYNC信号时就无法正常进行渲染操作,就会发生丢帧现象,并且在下一个渲染周期即32ms内用户看到的都是同一帧画面,当这种情况密集发生时,用户就能感知到明显的卡顿现象了。
Why 16ms?
这个问题和Why 60fps?是同样的
在搞清楚这个问题前,我们需要知道两个概念
1、refresh rate(刷新率)
它表示每秒刷新屏幕的次数,有硬件决定,如60HZ
2、frame rate(帧率)
它表示GPU每秒绘制的帧数,如60fps
GPU会获取图形数据进行渲染,然后通过硬件将渲染的图形显示到屏幕上
理想情况下,帧率应该大于屏幕的刷新率才能保证画面的流畅显示,但当帧率大于刷新率时GPU产生的帧数据会因等待VSYNC信号被保持住,这样能够保证每一次屏幕刷新都有新的帧被显示,但实际情况下更多的是帧率低于屏幕刷新率,这种情况下某些帧显示的画面会和上一帧相同,更糟的情况是当帧率突然升高或者降低时,会产生明显的卡顿不顺畅问题。
因此保证帧率就是解决卡顿问题的方法,人手动快速翻书的帧率大概是12fps,这时能够明显的看到卡顿现象,电影的帧率时24fps,这个帧率能够满足大部分图像的显示,但是低于30fps无法流畅地显示非常绚丽精细的图像,因此我们需要60fps来满足这一需求,大于60fps没有必要。因此我们必须保证在1000/60=16ms处理所有的任务,包括渲染。
为了更好的理解性能问题,我们首先需要搞清楚android系统如何利用GPU将XML中的UI控件渲染并显示到屏幕上的。这样的过程需要CPU和GPU协作完成,CPU负责将UI组建计算成Ploygon和Texture,然后交给GPU进行栅格化处理(就是将UI组建拆分成不同的像素,这是一个非常耗时的操作),CPU将数据转交给GPU的操作是一件很繁琐的事情,但是OpenGL ES能够将这些需要渲染的纹理保存在GPU的缓存中,下次需要时直接进行渲染操作就行了。Android中提供的资源如bitmap都是通过drawables打包在纹理中,然后传递到GPU中进行渲染的,这就意味着,每次需要这些资源时都是从纹理中获取的,文字的显示更加复杂,动画更甚之。

android性能优化——渲染性能_第1张图片
为了能使我们的App流畅,我们需要在16ms内完成CPU的计算,传递纹理,绘制渲染等操作。
Android系统将XML的布局文件转换成GPU能够识别并绘制的对象,这个操作是在DisplayList帮助下完成的,DisPlayList保存着所有将要交给GPU渲染的数据。
在某个View需要被渲染时,DisplayList被创建,当这个View要被显示到屏幕上时,就要执行GPU指令来进行渲染操作,如果后续执行类似移动这个View的动作时而需要渲染这个View时,只需要执行渲染指令并更新到屏幕上就行了。
要注意的是:当View的内容发生变化时DisplayList就会重新执行创建DisplayList、渲染DisplayList和更新屏幕等一系列的操作,这个过程的性能取决于View的复杂程度,View的状态变化和渲染管道的执行性能。例如,在增大一个View的大小前,需要通过其父View去计算其他子View的位置,如果这个布局非常复杂就会带来严重的性能问题。
因此引起性能问题的一个重要的方面就是复杂的绘制操作,OverDraw(过度渲染),表示某个像素在同一帧中被绘制了多次,引起这一问题的原因通常是在多层次的布局中,被隐藏的View也在做绘制操作导致的,这样会大量浪费CPU和GPU的资源。我们可以通过减少OverDraw的情况来获得更好的性能。
但是对于高度自定义的复杂View(重写了onDraw方法),Android无法检测到onDraw中做了哪些操作,系统无法进行监控和优化,也就无法避免OverDraw了,但是我们可以通过canvas.clipRect()帮助系统识别可见区域。这个方法可以指定特定的矩形区域,只有在这一区域才能被绘制,其他区域会被忽略,绘制指令不会被执行,部分在这个区域内的组件仍然会被绘制,这样可以大大节约CPU和GPU资源。同时还可以通过canvas.quickreject()方法快速判断是否与矩形区域相交,从而跳过非矩形区域组件的绘制。
android性能优化——渲染性能_第2张图片

你可能感兴趣的:(android性能优化)