• 我们可能有一个共同的误区:那就是认为使用基本的Layout结构是最有效的。但是,每一个添加到系统的组件都需要初始化,进行布局,绘制的过程。比如,使用在LinearLayout里面使用子组件会导致一个过于deep的层级结构。而且内嵌使用包含layout_weight属性的LinearLayout会在绘制时花费昂贵的系统资源,因为每一个子组件都需要被测量两次。在使用ListView与GridView的时候,这个问题显的尤其重要,因为子组件会重复被创建】


Inspect Your Layout(检查你的布局)


Android SDK里面包含了一个叫做Hierarchy Viewer的工具,在程序运行的时候分析布局文件,从而找住性能瓶颈

连接上设备,打开Hierarchy Viewer(定位到tools/目录下,直接执行hierarchyviewer的命令,选定需要查看的Process,再点击Load View Hierarchy会显示出当前界面的布局Tree。在每个模块的Traffic light上有三个灯,分别代表了Measure, Layout and Draw三个步骤的性能。

android 设置density 160 android 设置布局层级_Layout

Figure 1. ListView每个Item的常见布局.

android 设置density 160 android 设置布局层级_控件_02

Figure 2. 上面显示了对应与图片1的布局层级信息.可以看到中间LinearLayout的Measure的灯是红色的,这就是因为上面说到的:使用内嵌layout_weight的属性的LinearLayout会导致测量时花费了双倍的时间。

android 设置density 160 android 设置布局层级_ci_03

Figure 3. 点击某个模块会显示具体每个步骤所花费的时间。


Revise Your Layout (校订你的Layout)

【使得Layout宽而浅,而不是窄而深(在Hierarchy Viewer的Tree视图里面体现)】

上面的布局我们可以使用RelativeLayout来替代LinearLayout,从而实现shallow and wide.

android 设置density 160 android 设置布局层级_ci_04

Figure 4. 改用RelativeLayout来实现图片1的布局。

可以看到这是一个小的优化,可是这带来的效果是明显的,因为在ListView里面会出现很多这样的布局。

导致前面的case会出现花费时间比较多的愿意是使用了layout_weight在LinearLayout。我们需要仔细评估到底是否需要使用那样的

布局,尽量避免使用layout_weight。


Use Lint (使用Lint)


Lint是一款在ADT 16才出现用来替代layoutopt的新型工具,具有更强大的功能。

Lint的使用规则如下:

  • Use compound drawables - A 

LinearLayout

  •  which contains an 

ImageView

  •  and a 

TextView

  •  can be more efficiently handled as a compound drawable.
  • 【使用compound drawables - 一个包含了ImageView与TextView的LinearLayout可以被当作一个compound drawable来处理】
  • Merge root frame - If a 

FrameLayout

  • 【使用merge根框架 - 如果FramLayout仅仅是一个纯粹的(没有设置背景,间距等)布局根元素,我们可以使用merge标签来当作根标签】
  • Useless leaf - A layout that has no children or no background can often be removed (since it is invisible) for a flatter and more efficient layout hierarchy.
  • 【无用的分支 - 如果一个layout并没有任何子组件,那么可以被移除,这样可以提高效率】
  • Useless parent - A layout with children that has no siblings, is not a 

ScrollView

  •  or a root layout, and does not have a background, can be removed and have its children moved directly into the parent for a flatter and more efficient layout hierarchy.
  • 【无用的父控件 - 如果一个layout只有子控件,没有兄弟控件,并且不是一个ScrollView或者根节点,而且没有设置背景,那么我们可以移除这个父控件,直接把子控件提升为父控件】
  • Deep layouts - Layouts with too much nesting are bad for performance. Consider using flatter layouts such as 

RelativeLayout

  •  or 

GridLayout

  • 【深层次的layout - 尽量减少内嵌的层级,考虑使用更多平级的组件

RelativeLayout

  •  or 

GridLayout来提升布局性能,默认最大的深度是10

android 设置density 160 android 设置布局层级_Layout_05



在Eclipse里面使用的lint时候,lint会自动解决一些bug并且对其它一些问题给出相应的建议同时跳转到代码相应的地方让我们可以查阅代码。如果没有使用eclipse开发,那么你也可以从命令行里面去启动lint。具体情况可以参看“http://tools.android.com/tips/lint”。