Android性能优化之路(二)

路漫漫其修远兮,吾将上下而求索。

上次讲到了什么是Android设备的卡顿以及定位卡顿的原因的工具。这次来看看与屏幕绘制相关。

GPU过度绘制(Overdraw)是什么?

Overdraw是指在一帧的时间内(1/60s)像素被绘制了多次。理论上的最优是只绘制一次,但是重叠的布局会导致某些像素被绘制多次,当绘制像素的时常超过1/60s时,就会出现丢帧。

为了避免出现丢帧,使得程序运行的更加流畅,我们在设计UI的时候就需要考虑如何减少Overdraw的次数。

Android的开发者选项里提供了测量Overdraw的选项。


开发者选项->显示GPU过度渲染。如果打开没有效果的话,可以试试关闭掉硬件加速。

传送门:Android开发者选项-GPU显示配置文件无效


优化的原则就是:尽量避免重叠不可见元素的再绘制。

TIPS1:去除不必要的背景资源

扫描二维码关注公众号,回复: 2715487 查看本文章

在theme中添加android:windowBackground=”null”

在Activity中设置getWindow().setBackgroundDrawable(null),该语句需要写在setContentView()之后。因为setContentView()会默认给activity设置一个背景。


左图是没有设置activity背景为null,右图将activity背景设置为null.可见,上述的方法是有效的。

TIPS2:分段设置背景,尽量减少使用ViewGroup的嵌套层数。

上面的UI是用RelativeLayout嵌套实现的,嵌套层数为四层。现在将其改为LinearLayout来实现。


瞬间清爽了,有没有?完全没有Overdraw,整个背景层就只绘制了一次。

TIPS3:使用<merge>标签

Merge标签可以除去一个view的层级。

Merge标签的使用限制:子视图不能指定任何针对父视图的布局属性,例如:layout_centerHorizontal、layout_alignParentBottom等。

现有个RelativeLayout-TextView视图,如下:


此时TextView绘制了三次,RelativeLayout绘制了两次,Activity的背景绘制了一次。然后,再将RelativeLayout替换成Merge,如下:


瞬间绘制的次数都少了一次,有么有?

注:当使用Merge标签的时候,Activity的背景就不需要设置为空了,否则Merge标签不生效。

TIPS4:用9patch来做控件的背景,有效的减少控件的重叠区域。

应用场景:某控件需要设置边框背景,默认是用一张图片来做背景,在控件内再去绘制其他元素。这样至少其中的元素要被重绘两次。如果将背景用9patch图来做的话,控件内的其他元素则至少只用绘制一次即可了。

总结来说:过度重绘总是有办法解决的,但是需要针对不同情况采用不同的方法。灵活使用以上的方法,才可以达到预期想要的效果。




猜你喜欢

转载自blog.csdn.net/shirakawakanaki/article/details/53534526