1.过渡绘制

Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次重叠的UI结构里面,如果不可见的UI也在做绘制的操作,会导致某些像素区域被绘制了多次。这样就会浪费大量的CPU以及GPU资源。

当设计上追求更华丽的视觉效果的时候,我们就容易陷入采用越来越多的层叠组件来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳的性能,我们必须尽量减少Overdraw的情况发生。

幸运的是,我们可以通过手机设置里面的开发者选项,打开Show

GPU Overdraw的选项,可以观察UI上的Overdraw情况。

android app绘制渲染流程_UI

蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

产生的主要原因是:

不必要的背景颜色或背景图片

被遮挡的不可见部分

2.不必要的背景色或背景图片

通过一个例子,我们可以学习到怎样优化,可以从github下载源码

android app绘制渲染流程_背景图片_02

优化前后对比

主要优化点:

设置window的背景为null//The Theme's windowBackgroud is masked by the opaque backgroud of the activity,and
//the windowBackgroud causes an unnecessary overdraw.Nullifying the windowBackgroud
//removes the overdraw.
getWindow().setBackgroundDrawable(null);复制代码
清除xml不必要的background
按需显示占位背景图片// Display the chat author's avatar (a droid image) and a background color associated with
// the author.
if(chat.getAuthor().getAvatarId()==0){
Picasso.with(getContext()).load(android.R.color.transparent).into(chat_author_avatar);
chat_author_avatar.setBackgroundColor(chat.getAuthor().getColor());
}else{
Picasso.with(getContext()).load(chat.getAuthor().getAvatarId()).into(chat_author_avatar);
chat_author_avatar.setBackgroundColor(Color.TRANSPARENT);

 

3.被遮挡的不可见部分

Android系统知道过度绘制是个问题,它会设法避免绘制那些最终被遮挡而不显示的UI组件。这种优化叫做剪辑(clipping)。

但是不幸的是,对于那些过于复杂的自定义的View(通常重写了onDraw方法),Android系统无法检测在onDraw里面具体会执行什么操作,系统无法监控并自动优化,也就无法避免Overdraw了。但是我们可以通过canvas.clipRect()来帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。这个API可以很好的帮助那些有多组重叠组件的自定义View来控制显示的区域。同时clipRect方法还可以帮助节约CPU与GPU资源,在clipRect区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制。

除了clipRect方法之外,我们还可以使用canvas.quickreject()来判断是否没和某个矩形相交,从而跳过那些非矩形区域内的绘制操作。

通过一个例子,我们可以学习到怎样优化,可以从github下载源码。运行代码,可以看到如下图,这是一个层叠卡片的自定义view。被上层卡片覆盖的下层卡片依然绘制了,才产生红色过渡绘制提示。

android app绘制渲染流程_背景图片_03

android app绘制渲染流程_android过渡渲染_04

优化前onDraw方法

下面的代码显示了如何通过clipRect来解决自定义View的过度绘制,提高自定义View的绘制性能:

android app绘制渲染流程_UI_05

下面是优化过后的效果:

android app绘制渲染流程_自定义_06