Android布局优化

渲染基本知识

Android系统每隔16ms就重新绘制一次Activity,也就是说,我们的应用必须在16ms内完成屏幕刷新的全部逻辑操作,即每一帧只能停留16ms。
渲染操作通常依赖于两个核心组件:CPU与GPU:
* 在CPU方面,最常见的性能问题是不必要的布局和失效
* 在GPU方面,最常见的问题是我们所说的过度绘制(overdraw)

过度绘制

Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面, 如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。

开启过度绘制检测:设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示GPU过度绘制

过渡绘制

  • 蓝色: 意味着overdraw 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。
  • 绿色: 意味着overdraw 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
  • 淡红: 意味着overdraw 3倍。像素绘制了四次,小范围可以接受。
  • 深红: 意味着overdraw 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。

如何避免过度绘制

去掉window的默认背景

我们的Activity使用的Theme可能会默认的加上背景色,不需要的情况下可以去掉。

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">    
    <item name="windowBackground">null</item>
</style>

或者在Activity中进行设置

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().setBackgroundDrawable(null);
}

避免背景色的重复设置

有时候在根布局中设置了背景颜色之后,单独的View,比如TextView就可以不用再设置背景颜色了。
这个主要是结合UI设置,在写布局文件的时候稍加注意就可以避免的

clipRect的使用

我们可以通过canvas.clipRect()来 帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。

减少嵌套层次及控件个数

通过Hierarchy Viewer这个方便可视化的工具,可以得到:树形结构总览、布局view、每一个View(包含子View)绘制所花费的时间及View总个数。
备注: Hierarchy Viewer不能连接真机的问题可以通过ViewServer这个库解决;

Android的布局文件的加载是LayoutInflater利用pull解析方式来解析,然后根据节点名通过反射的方式创建出View对象实例;

Merge

减少视图层级。 至于为什么要减少视图层级上面已经说过了。
< merge/>标签可用于两种典型情况:
* 布局顶结点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity内容试图的parent view就是个FrameLayout,所以可以用merge消除只剩一个。
* 某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自动被忽略,而将其子节点全部合并到主布局中。

ViewStub

ViewStub称之为“延迟化加载”,不仅可以提高性能,也可以节省内存(初始化对象不被创建)。
App里常见的视图如蒙层、小红点,以及网络错误、没有数据等公共视图,使用频率并不高,如果每一次都参与绘制其实是浪费资源的,都可以借助ViewStub标签进行延迟初始化,仅当使用时才去初始化。

<ViewStub
    android:id="@+id/view_stub"
    android:layout="@layout/item_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
ViewStub viewStub = (ViewStub)view.findViewById(R.id.view_stub);
viewStub.inflate();

include

这玩意儿其实对于布局优化没有多大的作用,但是也是布局中的一个技巧。
主要功能是对布局进行复用

SpaceView

Space标签于4.0添加的,继承自View主要用于占位,google官方解释为

Space is a lightweight View subclass that may be used to create gaps between components in general purpose layouts.

Space是一个轻量级的View,一般用于分隔组件,布局或者在组件布局之间产生间隔

Android中RelativeLayout和LinearLayout性能分析

直接说结论:

  1. RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure。 所以LinearLayout在没有weight时,效果要更高一点
  2. RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin。
  3. 在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout。

View优化

从内优化

  1. 减少View层级
  2. 去除不必要的背景
  3. 尽可能减少使用margin,padding,可以在父View中控制。
  4. 去除不必要的scollbar(onDraw)
  5. 减少使用渐变(onDraw)

从外优化

  1. 布局嵌套过于复杂
  2. View的过度绘制
  3. View的频繁重新渲染
  4. UI线程中进行耗时操作
  5. 冗余资源以及错误逻辑导致加载和执行缓慢
  6. 频繁触发gc,导致渲染受阻

布局小技巧

viewFillper

android:clipChildren

android:clipToPadding

相关链接

Android 性能优化(二)之布局优化面面观
Android性能优化第(十)篇—布局优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值