Android的布局千姿百态,系统提供的布局数不胜数。但是往往有很多人忽略了优化和性能起手就在同一个Layout里疯狂写下整个布局代码。这明显是很不合理的一件事。下面来介绍一下Android布局的优化方式**

布局的层级以及测量次数

合理的选择父容器,这里推荐优先使用FrameLayout,其次LinearLayuut和RelativeLayout。但RelativeLayout会测量两次(这里提一下:如果能在减少层级的前提下尽量使用RelativeLayout)除了这三个父容器。着重关注ConstraintLayout
如果需求吻合请使用ConstraintLayout

总结:优先布局层级少的方案,层级相同则使用测量次数少的布局

如何查看布局层次呢?

使用Android Studio自带的Component Tree即可

Android布局的优化方式 - 图1

布局的优化方法

  1. include标签
    include的作用是引用另外一个布局从而不必重新编写布局,通常配合merge标签使用
    Android布局的优化方式 - 图2
    图中include引用了多个布局;美中不足的是让布局多了一个层级
  2. merge标签
    merge标签是include标签的一个辅助标签,目的就是让嵌套的布局减少层级,使用merge后:里面的View会成为父布局中的子View
    Android布局的优化方式 - 图3
    观察Component Tree发现层级少了一层
  3. ViewStub标签
    ViewStub继承自View,它是一个轻量级且宽高为0的组件,本身不参与布局和绘制。因此使用它可以做到在不需要的时候不加载,在需要的时候再加载,从而提高性能。通过setVisiable(View.Visiable)或者findViewById().inflate()使用

过度绘制

过度绘制是指在屏幕某个像素内同一帧被绘制多次,浪费大量的cpu和gpu资源

手机的开发者模式中会有一项为调试GPU过度绘制>显示GPU过度绘制,设置后,打开任何一个app,就可以看到界面上出现蓝、绿、粉、红四种颜色中的一种或者多种。

蓝色:1次过度绘制

绿色:2次过度绘制

粉丝:3次过度绘制

红色:4次过度绘制

解决方案如下:

  1. 去掉不必要的背景,如果父布局设置了背景,子View可不必再设置
  2. 去掉Windwo的默认背景
    一般来说我们使用的Activity都会有一些默认的主题,通常这个主题会有一个对应的背景,被DecoreView持有,我们自定义布局时如果又添加了一个背景图或者设置背景色,就会产生一个overdraw,因此可以考虑去掉默认的背景。
    我们可以在onCreate()的setContentView之前调用
    getWindow().setBackGroundDrawable(null)
  3. 优化onDraw方法;避免在onDraw中创建对象。因为onDraw方法可能会被调用多次