多层ViewGroup性能

来源:互联网 发布:windows用cmd卸载软件 编辑:程序博客网 时间:2024/05/17 08:44

<span style="font-size:18px;">原文地址:http://periplanisi.com/android/2013/11/multi-pass-viewgroup-and-performance/</span>

       回溯到2009年,罗马一个家伙写了一篇很有意思的文章,解释了使用RelativeLayout相比于使用LinearLayout的一些好处。不幸的是,很多人读了那篇文章之后,都信奉用RelativeLayout是更好的选择。然而,这却是一个完全错误的结论。

       然而这篇文章是非常好的,它提供了一些方法去减少布局的深度,和UI组件的使用数量。当然,第一条原则就是尽可能的去让你的布局扁平化,减少不必要的viewGroup组件,使用merge标签等。

       然而文章说的那些方案,并不能保证RelativeLayout会比LinearLayout表现出更好的性能。事实上你去检查RelativeLayout的实现,你会发现,RelativeLayout会调用子View的onMeasure方法两次!这必然会降低性能。如果RelativeLayout没有很深的子View层次,这种性能的影响可能还没那么严重,但是RelativeLayout如果作为一个布局的根View,并且包含很多的子View,那么这种性能影响可能很大。所以最好避免使用RelativeLayout作为布局的根View。

       当LinearLayout使用Weight属性的时候,为了去准确测量出所有子view 的尺寸,同样存在上面的问题(会调用子View的onMeasure两次)。所以使用LinearLayout的时候要注意Weight属性的使用。

       另外在View使用中还有一件需要注意的事情就是,listView的使用性能。listview使用wrap_content属性同样会降低性能,因为listview存在很多行元素,测量会比较耗时。所以说除非是不得已,否则一定要用match_parent。

       下面我们会给一些简单的例子来说明这些问题。

       假设我们的Activity加载这样一个布局,根View是用RelativeLayout,里面有一个子View是ListView,ListView的布局属性是wrap_content。

<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <ListView        android:id="@+id/mylist"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></RelativeLayout>
    然后我们提供一个BaseAdapter,加载下面的布局作为ListView每行的布局。注意到这里的布局的根View也是RelativeLayout。

<RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    >        <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/some_text"        />    </RelativeLayout>
       运行上面的试验,ListView在屏幕上面创建了20行数据,但是我们发现onMeasure一共被调用了320次!

    通过上面的分析,我们知道这里有三个点可以去做优化。

    1、把Activity布局的RelativeLayout改成LinearLayout

    2、把ListView的属性从wrap_content改为match_parent

    3、把ListView每行布局的RelativeLayout改为LinearLayout

     果不其然,我们发现优化之后,onMeasure的调用降低到了40次(降低8倍),同时Activity的加载时间降低了100ms(这个依赖设备)。当然,如果我们对一个更加复杂的View去做优化会有更好的效果。

    在4.4的系统中,做了一些缓存策略去优化这种过度的onMeasure调用。



0 0
原创粉丝点击