Android中RelativeLayout与LinearLayout的性能分析

  • Post author:
  • Post category:其他

大量参考

简书作者–尹star《Android中RelativeLayout和LinearLayout性能分析》

现象

新建xml文件时,默认的根布局是RelativeLayout;而我们setContentView()设置的布局的父布局却是LinearLayout(当前window的顶级View—DecorView(FramLayout)的子View),那么相同情景下到底那个更好呢?

Window和DecorView

Android中的视图都是通过Window来呈现的,不管Activity,Dialog还是Toast他们都有一个Window,然后通过WindowManager来管理View。Window和顶级View—DecorView之间的通信是依赖ViewRoot完成的。

性能比较

测试

主要是3个方法,onMeasure(),onLayout(),onDraw()
可以自己自定义控件测试。
通过测试,我们发现LinearLayout的onMeasure()耗时仅是RelativeLayout的一半左右。

原因

通过查看RelativieLayout与LinearLayout的onMeasure()方法发现,RelativeLayout的对子View测量了两次。为什么要测量两次呢?

  • 在RelativeLayout中View的排列顺序和实际要显示的顺序并不一定相同,所以要对子View进行排序。(个人觉得这个并不是原因)
  • 在RelativeLayout中View存在横向和纵向上的依赖。所以,源码中是对子View分别进行了横向和纵向的测量。

在LinearLayout中,是先判断方向,然后onMeasure()。但是如果遇到有weight属性的子View,会对其进行第二次的onMeasure()。so, try not to use “weight” as possible as you can.

RelativeLayout中的padding与margin

源码:

View的measure()方法

问题描述:

View的measure方法对绘制过程做了一个优化,如果我们的子View没有强制舒心,父View给子View的出入职也没有变化(也就是说子View的位置没有变化),就不会做武威的measure。但是RelativeLayout要做两次measure,在做横向测量时,纵向测量结果尚未完成(源码中先做的横向测量),只好暂时使用myHeight出入子View 系统,如果子View有margin属性,那么子View的高度和实际高度是不同的,那么这个优化也就没有意义了。

解决方法

使用padding代替margin

现象的回答

  1. 同等情况下,LinearLayout的性能优于RelativeLayout,所以setContentView()的父布局是LinearLayout
  2. 在尽量减少布局嵌套的情况下,RelativeLayout可以比LinearLayout写出更复杂的布局

版权声明:本文为xiangxiang07原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。