Android开发Android开发经验谈

Android 几种布局OnMeasure方法的测试

2017-10-20  本文已影响442人  森码

大家总是说提高绘制效率,也知道一些技巧,但是在界面出现卡顿的时候怎样去对症下药才是重点。比如:过度绘制,Google为开发者提供了很好的开发者工具,打开之后一眼就能看出,但是对于过度嵌套的问题呢?打开Hierarchy View都好麻烦,今天就测试一下几个组件的绘制情况,对优化有一个相对具体的概念,就知道该如何下手了。

一般布局

0、准备
先来看单层嵌套(即一个ViewGroup,一个TextView)
自定义ViewGroup、自定义TextView(ViewGroup分别继承LinearLayoutRelativeLayoutFrameLayoutConstraintLayout

layout.xml

1、LinearLayout

LinearLayout.png
onMeasure onLayout onDraw
LinearLayout 2 1 0
TextView 2 1 1
TextView(weight=1) 4 1 1

我们从表中分析三个方法的执行次数,主要是OnMeasure()方法,因为布局中的各个元素都是按照measure->layout->draw的顺序执行,为保证元素处于正确的位置、拥有正确的大小,measure方法在不同的ViewGroup中执行的次数差异是比较大的,此处我们也是着重比较这个。

2、RelativeLayout

RelativeLayout.png
onMeasure onLayout onDraw
RelativeLayout 2 1 0
TextView 4 1 1

3、FrameLayout

FrameLayout.png
onMeasure onLayout onDraw
FrameLayout 2 1 0
TextView 2 1 1

4、ConstraintLayout

ConstraintLayout.png
onMeasure onLayout onDraw
ConstraintLayout 2 1 0
TextView 2 1 1

从对比中可以看出,除RelativeLayout之外,其实各个ViewGroup间差别不大,大家可以根据需要随意使用,但是在出现双重甚至多重嵌套的时候就要注意了。


多重嵌套

0、基本布局

基本布局.png

1、Linear+Linear

onMeasure onLayout onDraw
Linear 2 1 0
Linear2 2 1 0
TextView 2 1 1
TextView(weight=1) 4 1 1
Linear+Linear.png
onMeasure onLayout onDraw
Linear 2 1 0
Linear2 2 1 0
TextView 2 1 1
TextView(weight=1) 4 1 1

2、Relative+Relative

Relative+Relative.png
onMeasure onLayout onDraw
Relative 2 1 0
Relative2 4 1 0
TextView 8 1 1

3、Linear + Relative(外层是LinearLayout)

Linear+Relative.png
onMeasure onLayout onDraw
Linear 2 1 0
Relative 2 1 0
TextView 4 1 1

4、Frame + Frame

Frame+Frame.jpg
onMeasure onLayout onDraw
Frame 2 1 0
Frame 2 1 0
TextView 2 1 1

5、Constraint + Constraint(其实这只是测试,真实情况应该避免这样使用)

Constraint+Constraint.jpg
onMeasure onLayout onDraw
Frame 2 1 0
Frame 4 1 0
TextView 4 1 1

通过测试,大部分情况都是可以接受的,除了第二种Relative的嵌套,如果有2次甚至3次嵌套,这简直就是灾难性的。

当然,这只是得出了一个概念,具体使用的时候大家按需所用就可以,简单的界面使用LinearLayout就好,如果出现需要双重Relative的时候记得用Constraint替换就可以,当然这并不能说执行的次数少就快,因为并没有做运行时间测试,但是从侧面表现出布局选择的重要性,如果有兴趣的同学可以用Android的Hierarchy View继续测试。如果你想要极致的性能,可以自定义ViewGroup,可参考自定义ViewGroup的例子,至于这是为什么当然要从源码里面找答案了,网上这样的解读很多,我就不赘述了。

其实,看了measure()里面的measureChild()方法就大概明白了: )

上一篇下一篇

猜你喜欢

热点阅读