美文网首页
性能探究之onMeasure

性能探究之onMeasure

作者: ZZombiee | 来源:发表于2018-07-04 12:11 被阅读0次

    虽然如今RecycleView大行其道,但作为老牌控件listview仍应用广泛,但真正使用时,由于业务上的需求以及开发人员的理解不深入,使得listview性能并不十分高,造成卡顿

    那么先从以下几点进行测试

    • 父布局类型(相对,线性)
    • 布局嵌套深度

    XML布局代码

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:orientation="vertical">
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="添加数据"/>
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onToggle"
            android:text="显示/隐藏"/>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@mipmap/ic_launcher"/>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
    
                    <ImageView
                        android:id="@+id/imageview"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@mipmap/ic_launcher"/>
    
                    <com.hhwant.speed.app.TestListView
                        android:id="@+id/listview"
                        android:layout_width="match_parent"
                        android:layout_height="200dp"
                        >
    
                    </com.hhwant.speed.app.TestListView>
    
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    

    根布局LinearLayout,再嵌套3层LinearLayout,内置一个自定义Listview,自定义Listview的代码很简单,只是单纯在onMeasure打印一段话

    public class TestListView extends ListView {
        private static final String TAG = "TestListView";
    
        public TestListView(Context context) {
            super(context);
        }
    
        public TestListView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public TestListView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            Log.d(TAG, "onMeasure");
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    

    先看LinearLayout多层嵌套下的效果

    LinearLayout_listview.jpg线性布局嵌套测试——无权重.gif
    • 可以见到的是在LinearLayout嵌套了3层的情况下,进入界面初始化调用了2次onMeasure()
    • 让与listview同层级的imageview消失(GONE)后,不会间接触发listview调用onMeasure
    • 让listview里的item图片visible或者gone,会同样的让listview调用一个onMeasure

    那么给ListView设置权重以后再看效果


    LinearLayout_listview.jpg线性布局嵌套测试——有权重.gif
    • 和前者的不同之处在于设置了权重以后,listview同级的imageview设置visible和gone后,会间接让listview重新调用onMeasure来重新计算listview的高度

    再来看看RelativeLayout多层嵌套下的效果

    RelativeLayout_listview.jpg相对布局嵌套测试.gif
    • 可以见到的是在RelativeLayout嵌套了3层的情况下,进入界面初始化调用了16次onMeasure() ,即2^4
    • 让与listview同层级的imageview消失(GONE)后,会间接触发listview调用8次onMeasure,即2^3
    • 让listview里的item图片visible或者gone,会同样的让listview调用8次onMeasure,即2^3

    因RelativeLayout的特殊性,功能的丰富性同时导致了其性能的低下,在界面初始化时需调用两次onMeasure(),而RelativeLayout内部的onMeasure方法更是需要遍历子view,分别横向和纵向测量子view

    那么我们可以得出一个结论,在能实现需求和功能的前提下,基础布局尽量不选择RelativeLayout,特别是ListView在RelativeLayout的嵌套下,多次调用onMeasure(),而ListView又在onMeasure调用了getView,大部分的逻辑在getView中,指数次调用必然导致性能的大幅下降

    参考资料

    Android应用性能优化系列视图篇——三大基础布局性能比较
    Android应用性能优化系列视图篇——ListView自适应导致的严重性能问题
    Android源码(这个就自己进布局源码看吧)

    相关文章

      网友评论

          本文标题:性能探究之onMeasure

          本文链接:https://www.haomeiwen.com/subject/hcleuftx.html