Anroid性能优化系列——Improving Layout Performance(一)

时间:2022-11-07 05:55:27

(请关注我们的微信公众号:Java和Android大牛频道)

本文翻译自Google官方文档


Layouts是Android应用里直接影响用户体验的一个关键部分。如果Layout设计的不好,可能导致你的应用大量的内存占用而导致UI响应很慢。Android SDK提供了工具帮你分析Layouts的性能问题。结合这个工具同时查看本文,你能实现滑动流畅、占用内存最小的用户界面。


Optimizing Layout Hierarchies


一个复杂的Web页面可能需要很长的时间才能加载出来。同样地,你的Layout层次如果太复杂也可能引起性能问题。本文你讲看到如果通过SDK工具来发现你的Layout的问题和性能瓶颈。


Re-using Layouts with <include/>


如果你的应用UI在许多地方都存在重复的Layout结构。这课将告诉你如何产生有效的可复用的Layout,然后在合适的UI布局里include进它们。


Loading Views On Demand


除了简单地在一个Layout里include另一个布局组件外,有时候,你也可以在Activity启动起来后,仅仅当该Layout组件需要时才让其可见。这将告诉你怎么按需加载你的Layout的部分而提高Layout的初始化性能。


Making ListView Scrolling Smooth


如果你的app里需要一个ListView,而该ListView里的每一个Item拥有复杂的或者重量级的data,ListView的滑动性能可能是一个问题。这课也将给你一些优化页面滚动性能的建议。


Optimizing Layout Hierarchies


通常有个错误的概率:使用最基本的布局结构能产生最有效的Layouts。然而,每一个加到你Application里的Widget和Layout都需要初始化、布局和绘制。例如:使用嵌套的LinearLayout能导致非常深的视图层次。更进一步的,嵌套若干个使用layout_weight参数的LinearLayout将极大影响性能,因为每个子视图需要测量大小两次。当布局被重复渲染的时候这是特别耗费性能的。例如当使用ListView和GridView时。


本文你讲学到使用Hierarchy Viewer 和 Layoutopt工具检测和优化你的Layout


Inspect Your Layout


Android SDK工具集里有个名叫Hierarchy Viewer的工具。该工具能分析你的App运行时的Layout。用该工具你能发现你的Layout性能的瓶颈。


选择你的手机或者模拟器里运行的某个进程,然后通过该工具展示布局树。在每一个布局块里,信号灯代表了它的测量、布局和绘制的性能,帮助你分析潜在的问题。


例如,图一表明了一个ListView里的一个Item的布局。这个布局的左边展示一个简单的bitmap image,右边是两个TextView。像这个布局文件,可能被渲染多次。因此,优化布局性能就显得尤为重要。


Anroid性能优化系列——Improving Layout Performance(一)
 图一:Conceptual layout for an item in a ListView.


HierarchyViewer工具在<sdk>/tools/目录下。打开该工具,会显示有效设备列表和某个设备正在运行的组件。点击“Load View Hierarchy”查看这被选中的app的布局层次。


例如,图2,显示了上图一的布局。


 Anroid性能优化系列——Improving Layout Performance(一)


Figure 2. Layout hierarchy for the layout in figure 1, using nested instances ofLinearLayout.


Anroid性能优化系列——Improving Layout Performance(一)
Figure 3. Clicking a hierarchy node shows its performance times.


在图2,你能看到这个布局有3级层次结构。点击图2里的某个条目会告诉你每个阶段(测量、布局和绘制)处理所耗费的时间(见图3)。哪个条目花费了最多的测量、布局和绘制时间将变的一目了然。你也知道了在哪花时间优化。


渲染出该布局list里一个完整的item所需时间为:


 Measure:0.977ms
Layout:0.167ms
Draw:2.717ms


修正你的布局


因为上面的布局性能较慢归因于嵌套的LinearLayout,那么,我们可以是Layout变得宽而浅,而不是窄而深来优化布局。上面的布局我们可以使用RelativeLayout来替代LinearLayout。这样,该布局层次就变成了2级通过HierarchyViewer查看,你发现这新的布局变成了:


 Anroid性能优化系列——Improving Layout Performance(一)
Figure 4. Layout hierarchy for the layout in figure 1, using RelativeLayout.


现在展现一个item花费:

Measure:0.598ms
Layout:0.110ms
Draw:2.146ms


看上去可能只有那么一点点改善。但是在一个list里有多个Item,这些节省的时间累积起来效果就较明显了。大多数情况下,布局渲染时间差别较大的原因是在LinaerLayout里使用了layout_weight.这将会增加Measure的时间。这仅仅是一个合理的使用和优化Layout的例子,你应该仔细的考虑是否有必要使用layout weight。


Use Lint


使用Lint工具可以查看你的view 层级哪些地方可以优化。Lint已取代了Layoutopt 工具,它比Layoutopt提供了更多的功能。Lint使用的例子如下:

  • 使用compound drawables —— 一个包含了ImageView与TextView的LinearLayout可以被当作一个compound drawable来处理

  • 使用merge根框架 —— 如果FramLayout仅仅是一个纯粹的(没有设置背景,间距等)布局根元素,我们可以使用merge标签来当作根标签

  • 无用的分支 —— 如果一个layout并没有任何子组件,那么可以被移除,这样可以提高效率

  • 无用的父控件 —— 如果一个layout只有子控件,没有兄弟控件,并且不是一个ScrollView或者根节点,而且没有设置背景,那么我们可以移除这个父控件,直接把子控件提升为父控件

  • 深层次的layout —— 尽量减少内嵌的层级,考虑使用更多平级的组件 RelativeLayout or GridLayout来提升布局性能,默认最大的深度是10


Lint被集成进 Android Development Tools for Eclipse (ADT 16+)。Eclipse会自动运行Lint的工具,并给出相应的提醒,不管是在导出APK,编辑,保存XML还是在使用layout编辑器的时候。如果想强制运行,请参看上面的图标,点击运行。


Anroid性能优化系列——Improving Layout Performance(一)


如果没有eclipse开发环境,也可以在命令行中执行。