Android 性能优化——布局优化

摘要

本文先谈了下布局优化的必要性,然后阐述不好的布局会引发哪些问题,在针对这些情况提出具体的布局优化方案,同时介绍一些常用布局优化工具的使用。

参考文章:

必要性

为了避免手机资源的浪费(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首页卡段的问题,嘿嘿)。