优化布局层次结构

使用基本布局结构可打造最高效的布局是一种常见的误解。无论如何,您添加到应用中的每个微件和布局都需要进行初始化、布局和绘制。例如,使用 LinearLayout 的嵌套实例会导致视图层次结构过深。此外,嵌套多个使用 layout_weight 参数的 LinearLayout 实例成本非常高,因为每个子级都需要测量两次。如果要反复扩充布局(例如,在 ListViewGridView 中使用时),则要特别注意这方面。

在本课中,您将学习如何使用 Hierarchy ViewerLint 来检查和优化布局。

检查布局

Android SDK 工具包含一个名为 Hierarchy Viewer 的工具,可让您在应用运行时分析布局。使用此工具可帮助您发现布局性能方面的瓶颈。

通过 Hierarchy Viewer,您可以在已连接的设备或模拟器上选择正在运行的进程,然后显示布局树。各个块上的信号灯代表其测量、布局和绘制性能,有助于您识别潜在问题。

例如,图 1 显示了用作 ListView 中的一项的布局。此布局左侧显示了一张小小的位图,而右侧则显示了两个堆叠的文本项。尤其重要的是,将多次扩充的布局(例如此布局)已经过优化,因为性能优势将会成倍地提升。

图 1. ListView 中的一项的概念性布局。

Hierarchy Viewer 会显示可用设备及其正在运行的组件的列表。从 Windows 标签中选择您的组件,然后点击 Hierarchy View 查看所选组件的布局层次结构。例如,图 2 显示了图 1 所示列表项的布局。

图 2. 图 1 中的布局的布局层次结构,使用 LinearLayout 的嵌套实例。

修改布局

由于上述布局性能因嵌套的 LinearLayout 而有所下降,因此可以通过展平布局(使布局变浅变宽,而非变窄变深)来提高性能。作为根节点的 RelativeLayout 允许此类布局。因此,将此设计转换为使用 RelativeLayout 后,该布局便会成为 2 级层次结构。检查新布局是否如下所示:

图 4. 图 1 中的布局的布局层次结构,使用 RelativeLayout

这些优势可能看起来并不显眼,但却会成倍地提升性能,因为此布局用于列表中的每一项。

大部分差异都是由于在 LinearLayout 设计中使用 layout_weight 造成的,这会减缓测量速度。这只是如何恰当地使用每个布局的其中一个示例,您应仔细考虑是否有必要使用布局权重。

在一些复杂的布局中,系统可能会浪费时间和资源来多次测量同一个界面元素。这种现象称为 Double Taxation。如需详细了解 Double Taxation 以及如何防止出现这种情况,请参阅性能和视图层次结构

使用 Lint

对布局文件运行 lint 工具来搜索可能的视图层次结构优化始终是一种很好的做法。Lint 取代了 Layoutopt 工具,并提供了更加强大的功能。下面显示了 lint 规则的一些示例:

  • 使用复合可绘制对象 - 包含 ImageViewTextViewLinearLayout 可作为复合可绘制对象得到更加高效的处理。
  • 合并根框架 - 如果 FrameLayout 是一个布局的根,并且未提供背景或内边距等信息,则可以将其替换为稍微高效一些的 merge 标记。
  • 无用的叶子 - 没有子级或没有背景的布局通常可以移除(因为它不可见),以使布局层次结构更加扁平高效。
  • 无用的父级 - 如果一个布局含有子级但没有同级、不是 ScrollView 或根布局且没有背景,则可以将其移除或将其子级直接移动到父级,以使布局层次结构更加扁平高效。
  • 深层布局 - 嵌套过多的布局会降低性能。考虑使用 RelativeLayoutGridLayout 等比较扁平的布局来提高性能。默认的深度上限为 10。

Lint 的另一项优势是,它已集成到 Android Studio 中。Lint 会在您编译程序时自动运行。借助 Android Studio,您还可以针对特定编译变体或针对所有编译变体运行 lint 检查。

您还可以在 Android Studio 中使用 File > Settings > Project Settings 选项管理检查配置文件和配置检查。系统会显示“Inspection Configuration”页面,其中包含支持的检查。

图 5. 检查配置

Lint 能够自动修复某些问题、提供用于解决其他问题的建议,以及直接跳转到违规代码进行审核。

如需详细了解有关本课程的信息,请参阅 XML 布局布局资源