摘要
本文先谈了下布局优化的必要性,然后阐述不好的布局会引发哪些问题,在针对这些情况提出具体的布局优化方案,同时介绍一些常用布局优化工具的使用。
参考文章:
必要性
为了避免手机资源的浪费(CPU资源和GPU资源),减少卡顿的发生,必须对App的布局进行优化。优化可以从下三方面着手:
- 无必要的layout
- 过于频繁的invidations
- Overdraw
检测工具
- Android Device Monitor ——Hierarchy View,查看布局层级,看看有没有不必要的嵌套
- Android Studio->Tools->Layout Inspector
- 开发者选项——Show GPU Overdraw,查看视图的绘制情况
解决方案
Overdraw的检测
打开上面的Show GPU Overdraw后,App上会有不同的颜色显示当前的Overdraw情况:
- 蓝色, 1x overdraw
- 绿色, 2x overdraw
- 淡红, 3x overdraw
- 深红, 4x overdraw
如果红色区域较多,就说明当前页面过度绘制严重,需要我们解决了。
解决方案一:移除非必要的background
有时候为了统一UI效果,通常会设置整体的背景,这就可能导致父容器设置了背景,然后子容器也设置了背景,这时如果嵌套过深,就会出现严重的overdraw
DecorView也存在一层背景的,如果我们自己设置了跟布局的背景,我们可以将DecorView的背景置空:
1
getWindow().setBackgroundDrawable(null)
在设置背景是,要慎用layer-list。为什么呢?因为layer-list 本身就存在多层绘制。
解决方案二:在绘制的时候采用ClipRect
自定义控件的时候,如果涉及到矩形绘制,可以采用ClipRect,它可以很好的处理绘图区域的重叠部分
解决方案三:降低View的层级
如果View的层级过深,那么overdraw的概率就会加大,所以降低View的嵌套层级是解决Overdraw的最基本途径。减少View的层级,可以从以下几个方面入手:
选择合理的根布局,推荐使用ConstraintLayout(Android Studio 3.x以上的版本新建Activity默认的根布局就是采用ConstraintLayout),他结合了LinearLayout和RelativeLayout的特性,比提供了几个非常有用的辅助布局工具,如ViewGroup、GuidLine等。
merge标签的使用,比如一个View继承自FrameLayout,而它inflate的layout文件的根布局也是FrameLayout,这样就可以采用merge标签来代替根布局中的FrameLayout标签,通过很简单的方式就减少了一层嵌套。
HierarchyView使用
使用HierarchyView可以查看布局的层级,并针对某个布局来查看其measure、layout、draw的速度,从而检测问题可能发生的地方。
一般,在布局的时候,要注意一下几点:
- 避免RelativeLayout嵌套
- 尽量避免布局多层嵌套
- 使用include、merge等标签
- 使用ViewStub优化布局
- 不常用的布局使用GONE隐藏而不是INVISIBLE
总结
减少布局的嵌套,避免过渡重绘,经实践真的能提高App的性能(我有效的解决了公司App首页卡段的问题,嘿嘿)。