ConstraintLayout优缺点,真的能提升性能?

1、ConstraintLayout是什么?

废话,当然是布局类型了。以前的布局类型有5种:线性布局、帧布局、相对布局、表格布局、绝对布局,常用的其实也就是前面三种。
ConstraintLayout就是约束布局,就是根据控件与控件之间的约束条件来决定最后在界面上的位置。就好像拼图一样,每一块拼图都跟相邻的拼图有约束关系,而拼图的边和角就直接和相框有约束关系,从而最后组成一幅完整的图画。

2、为什么需要ConstraintLayout?

了解过或者做过布局优化的话,应该都了解,如果布局内的层数越多,越消耗性能。
image.png

可以看到,要绘制一个界面,就需要在树里面先找到叶子,确定好了叶子的大小和位置,再逐步向上遍历。简单的,也就是递归。所以当布局内的层数越多,那布局的计算也就越复杂。
而ConstraintLayout,就是让所有的布局内的view,都平铺在同一层,从而减少布局内的层数,优化界面的绘制消耗。

3、relativeLayout也可以达到单层布局,ConstraintLayout真的有用?

来试一试,先自定义2个View,分别继承relativeLayout和ConstraintLayout,并统计onMeasure的时间。

<?xml version="1.0" encoding="utf-8"?>
<com.example.test.view.MeasureTimeRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>

        <TextView
            ..../>
        <TextView
            ..../>
</com.example.test.view.MeasureTimeRelativeLayout>

这是相对布局的xml文件,我们多次启动,看看界面绘制的耗时:

image.png
每次进入界面,会触发2次onMeasure,可以看到,第一次测量的耗时,大概是3毫秒左右。
那再看看ConstraintLayout的耗时:
image.png
可以看到,耗时立马不对劲了起来,比RelativeLayout耗时多太多了,但是如果有留意到的话,你会发现,耗时是越来越少的,当进入界面的次数越来越多,界面测量的耗时就和RelativeLayout差不多一样了。为什么这样,稍后再研究。

4、如果层次多一点的界面,耗时怎么样?
<?xml version="1.0" encoding="utf-8"?>
<com.example.test.view.MeasureTimeRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/rl1"
        android:layout_width="match_parent"
        android:layout_height="300dp">

        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>
        <TextView
            ..../>

        <TextView
            ..../>
        <TextView
            ..../>
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/textView2"
            android:layout_centerHorizontal="true">

           
        <TextView
            ..../>
        </RelativeLayout>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/rl2"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_below="@id/rl1">

        <TextView
            ..../>

        <TextView
            ..../>

        <TextView
            ... />

        <TextView
            ... />

        <TextView
            ..../>
        
        <TextView
            ..../>
        
        <TextView
            ..../>
        
        <TextView
            ..../>
       
        <TextView
            ..../>
        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/textView22"
            android:layout_centerHorizontal="true">

        <TextView
            ..../>
        </RelativeLayout>
    </RelativeLayout>
</com.example.test.view.MeasureTimeRelativeLayout>

这是RelativeLayout的耗时:
image.png

这是ConstraintLayout的耗时:
image.png
google官网所说的性能优化,就这?看起来还不如RelativeLayout啊。
那我们为什么还要用ConstraintLayout?

其实,上面的情况是这样,只是因为布局内的元素还算是简单的搭配,但是随着界面的复杂度提升,还有一些view的计算,这时候ConstraintLayout的性能优势就体现出来了。
例如以下几个例子:
①根据中心view,其他view按照角度来定位布局。

image.png
②同一水平方向,多个view排列,中间的view长度变化不影响边缘view的显示
image.png
③图片按照一定比例显示

后两种已经是常见得不能再常见的需求了,但是如果不使用ConstraintLayout,只使用相对布局或者线性布局来实现,那就只能动态获取相应的文字宽度、图片的大小比例,之后再去计算填充到布局里了。
ConstraintLayout还有很多强大的属性,是其他布局做不到或者很难做到的,感兴趣的可以自行搜索研究。

那ConstraintLayout是怎么做到复杂的布局的性能优化的?

ConstraintLayout 的组成可以大致分为三个部分:ConstraintWidgetContainer,ConstraintWidget 和 Cassowary 算法(全称 The Cassowary Linear Arithmetic Constraint Solving Algorithm,有兴趣的同学可以自行搜索)。

ConstraintWidgetContainer 相当于引擎,ConstraintWidget 是所有 ConstraintLayout 所包含控件的抽象(每个child 对应一个 ConstraintWidget),ConstraintWidgetContainer 驱动 所有 ConstraintWidget 进入 Cassowary算法封装盒子,Cassowary 将计算好的 ConstraintWidget 输出交给 ConstraintWidgetContainer,这时,所有child 的布局数据都已经被计算出来,ConstraintLayout只需要把它们放在数据指示的位置即可。

还记得上面实验计算耗时的结果吗?ConstraintLayout的耗时随着进入界面的次数,是逐步减少的,为什么会这样?
其实这个不是ConstraintLayout干的优化结果,是Android的机制问题。
Android 2.2-4.4:
这部分都是使用JIT,就是说都是在运行的时候,需要用什么,就加载什么,好处就是安装贼快,但缺点也明显,每次运行都需要重新编译,浪费资源,例如电量。
Android L(5.0)- Android N:
安装时直接使用预先编译(AOT),就是把所有代码一次性转化为本地机器码,当需要使用时就可以直接使用了。但是缺点就是第一次安装的时候十分的慢,因为一次性转化全部代码很耗时。
Android N(7.0)以上的:
安装apk的时候,不进行任何的预编译(提高安装速度);
运行的过程中解析执行,并且对经常使用的方法进行优化,就是即时编译(JIT just in time),经过JIT处理的代码,都会记录在一个profile配置文件里;
最后在手机闲的时候,有一个编译守护进程,会对profile里面的方法进行预先编译(AOT),把这些代码转化为本地机器码。
是由于这个原因,使得ConstraintLayout的耗时越来越少的。如果拿几台对应的系统版本手机来测试,你就会发现5.0-N的是耗时最少的,而且耗时不变。而另外2种,耗时都是逐渐减少。

那ConstraintLayout有啥缺点?

纯个人观点:
①要多写点属性
②牵一发而动全身,有时候改一个控件,布局全变了(所以一定要找好作为锚的控件)
③如果界面布局不是很复杂,性能甚至比旧的布局类型还要差
④复杂的界面,所用元素都放在统一平面上,代码的可读性会十分差

总结:

①不要一股脑全用ConstraintLayout,简单的布局,还是其他布局类型较好。
②网上一堆说ConstraintLayout的性能优化,都好像只是说布局的嵌套层数问题,其实并不是,需要看实际情况。
③就算ConstraintLayout能做到全部元素放在统一父布局内,也应该适当地分层

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容