层级优化

measure、layout、draw这三个过程都包含自顶向下的View Tree遍历耗时,如果视图层级太深自然需要更多的时间来完成整个绘测过程,从而造成启动速度慢、卡顿等问题。而onDraw在频繁刷新时可能多次出发,因此onDraw更不能做耗时操作,同时需要注意内存抖动。对于布局性能的检测,依然可以使用systrace与traceview按 照绘制流程检查绘制耗时函数。

Layout Inspector

在较早的时代SDK中有一个hierarchy viewer 工具,但是早在 Android Studio 3.1 配套的SDK中就已经被弃用。现在应在运行时改用 Layout Inspector来检查应用的视图层次结构。

android onDraw 保存上一帧 android ondraw是否频繁绘制_android studio

然后选择需要查看的进程与Activity:

android onDraw 保存上一帧 android ondraw是否频繁绘制_初始化_02


在左侧id为content之下的就是我们写在XML中的布局。可以明显看出,我们的布局中是一个LinearLayout,其中又包含两个LinearLayout。我们应该尽量减少其层级,可以使用ConstraintLayout约束布局使得布局尽量扁平,移除非必需的UI组件。

android onDraw 保存上一帧 android ondraw是否频繁绘制_android studio_03

使用merge标签

当我们有一些布局元素需要被多处使用时,这时候我们会考虑将其抽取成一个单独的布局文件。在需要使用的地方通过 include加载。

使用ViewStub 标签

当我们布局中存在一个View/ViewGroup,在某个特定时刻才需要他的展示时,可能会有同学把这个元素在xml中 定义为invisible或者gone,在需要显示时再设置为visible可见。比如在登陆时,如果密码错误在密码输入框上显示提示。

nvisible
view设置为invisible时,view在layout布局文件中会占用位置,但是view为不可见,该view还是会创建对 象,会被初始化,会占用资源。
gone
view设置gone时,view在layout布局文件中不占用位置,但是该view还是会创建对象,会被初始化,会占 用资源。

如果view不一定会显示,此时可以使用 ViewStub 来包裹此View 以避免不需要显示view但是又需要加载view消耗资源。
viewstub是一个轻量级的view,它不可见,不用占用资源,只有设置viewstub为visible或者调用其inflater()方法 时,其对应的布局文件才会被初始化。