Android性能典范渲染篇 — — 6.clipRect()和quickReject()使用介绍

It’s worth pointing out that the Android framework knows that overdraw is a problem, and will go out of its way to avoid drawing UI widget that may be invisible in the final image.This type of optimization, called clipping, is highly important to UI performance.

值得指出是Android Framework 会判断界面是否有过度重绘的问题。并且能够以它自己的方式去避免绘制那些没有在最终图像上显示的UI组件。那种类型的优化对于UI性能非常重要,我们叫截断绘制。

If you can determine an object will be fully obscured, there’s no reason to go about drawing it. In fact this is actually one of the most important performance optimization that Android performs.


But sadly this technique doesn’t extend itself to complex custom views, where you’re overriding the canvas dot on draw method. In these cases, the underlying system doesn’t have insight into how you’re drawing your content, which makes it really hard for it to remove hidden views from your rendering pipeline.


For example,in this stack of cards, only the top card is fully visible and the rest of the cards are mostly hidden, which means that drawing all of those overlapping pixels is wasted processing time. To address this problem, the canvas class is equipped with a few special methods that you can use to tell the Android Framework what parts of the canvas are hidden and don’t need to be drawn.

举个例子,在这些卡片中,只有顶部的卡片式是完整显示,而其余的卡片则是大部分被隐藏,而绘制这些重叠的像素点是在浪费时间。为了解决这个问题,Canvas类里有几个特殊的方法,可以用来告诉Android Framework 在自定义view中哪些部分是隐藏而不需要被绘制的。

The most useful method is canvas dot clipRect, which allows you to define the drawable boundaries for a given view, meaning that if any canvas drawing happens outside these boundaries, it’ll be ignored. This could be really helpful when you’ve got this type of staggered view, like our cards for example.


If you know how much of your custom view is visible, or rather you know how much is obscured, you can define the clipRect boundaries, which will prevent any drawing from happening in the obscured areas.


Now the clipRect API helps the system know what to avoid drawing.But it would also be helpful for your custom view to do some of this work on its own, ahead of time for example, it would be really helpful if you knew what you were going to draw if it’s actually outside of the clipping rectangle.

Fortunately, you don’t have to figure out all that intersection logic yourself, the canvas.quickReject method tests whether a given area is completely outside the clipping rectangle, in which case you can skip all that drawing work. Now let’s take a look at a common situation where this happens and take a swing at fix it.