提升APP性能,保持运行流畅,这是开发者们一直都在解决的问题。至于性能优化,包括很多方面,下面谈谈Android布局相关的优化。
一、优化layout的层级
1.1、避免嵌套过深Layout结构如果太复杂,导致整个测量、布局和绘制过程过于复杂、容易造成性能问题。
嵌套的 LinearLayout 可能会使得 View 的层级结构很深。
使用LinearLayout时,通常我们喜欢用嵌套的布局来动态设置一个View的Visibility ,由于LinearLayout是线性的,因此即使隐藏一个View也不会影响到其它View的排列。而在RelativeLayout中,View的位置都是相对于其它View的,因此,隐藏之后,会导致之前的View没有参考对象了,导致的相对位置改变,这时你可以使用alignWithParentIfMissing=”true”来处理这种情况。
此外,嵌套使用了 layout_weight 参数的 LinearLayout 的计算量会尤其大,因为每个子元素都需要被测量两次。这对需要多次重复 inflate 的 Layout 尤其需要注意,比如使用 ListView 或 GridView 时。
因此开发中尽量使用RelativeLayout
1.2、使用merge标签优化层级
减少根布局相同的情况
1.3、使用<include/>标签重用Layout
二、按需加载
3.1、不需要立即加载的布局,设置为GONE,系统会跳过,不加载
3.2、使用ViewStub 实现按需加载
在开发中经常会遇到这样的情况,会在程序运行时动态根据条件来决定显示哪个View或某个布局。那么通常做法就是把用到的View都写在布局中,然后在代码中动态的更改它的可见性。但是它的这样仍然会创建View,会影响性能。
这时就可以用到ViewStub了,ViewStub是一个轻量级的View,不占布局位置,占用资源非常小。
三、容器列表类的优化
比如ListView的优化
如果你有一个包含复杂或者每个项 (item) 包含很多数据的 ListView ,那么上下滚动的性能可能会降低。
保持程序流畅的关键,是让主线程(UI 线程)不要进行大量运算。你要确保在其他线程执行磁盘读写、网络读写或是 SQL 操作等。为了测试你的应用的状态,你可以启用 StrictMode。
3.1、使用后台线程
你应该把主线程中的耗时间的操作,提取到一个后台线程中,使得主线程只关注 UI 绘画。
3.2、在 View Holder 中填入视图对象
减少重复的findViewById()
3.3、getView不要做复杂的操作
因为每一条Item移入屏幕的时候,都会调用getView,不要在getView中做复杂的操作,不要频繁的创建对象。
四、避免过度绘制
屏幕上某一像素点在一帧中被重复绘制多次,就是过渡绘制。
设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示GPU过度绘制
2、Overdraw 的处理方案
1)、防止Theme和Activity的背景色重复设置
如果Activity使用了主题,默认情况下,新建一个Activity都是有背景的。正常情况下,很多界面其实是不需要背景的。
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.NoActionBar">
<item name="android:windowBackground">@color/white</item>
</style>
android:windowBackground可设置背景颜色,如果Activity不想用主题的颜色,可以在onCreate中
getWindow().setBackgroundDrawable(null);
然后在layout中设置自己的背景颜色。
2)、使用Canvas的clipRect和clipPath方法限制View的绘制区域
一个Activity对应有一个Canvas,也就是画布,画布的概念就是一个画板,这个画布提供了很多的API,我们可以通过调用画布的API来绘图以及对画布做一些操作,clipRect方法用来裁切画布上的一个矩形区域,该矩形区域用Rect对象来描述。调用了clipRect之后,画布的可绘制区域减小到和Rect指定的矩形区域一样大小。所有的绘制将限制在该矩形范围之内。
3)、ImageView的background和imageDrawable重叠
Android中,所有的view均可以设置background。ImageView除了能够设置background之外,还能设置ImageDrawable。
在开发中,很多时候需要显示图片,在图片加载出来之前通常是需要显示一张默认图片的,很多时候会使用ImageView的background属性来设置默认背景图,而imageDrawable来设置需要加载的图片。这样会导致一个问题,当图片加载到页面后,默认背景图被挡住了,但是却任然需要绘制,导致过渡绘制情况的发生。
解决方案是把背景图和真正加载的图片都通过imageDrawable方法进行设置。
4)、减少不必要的层次,巧用Hierarchy Viewer
五、其他优化技巧
1、用TextView同时显示文字和图片
drawaleLeft、drawableRight、drawableTop、drawableBottom
2、TextView的行间距
android:lineSpacingExtra="8dp"
可控制多行显示,并设置行间距
3、使用Spannable或Html.fromHtml
对于一行文字中有不同文字大小、颜色、链接、点击事件等,可使用Spannable减少TextView的个数
4、Space控件设置间隔
比如要给条目列表添加间距,怎么实现呢?当然也很简单,比如添加一个高10dp的View,或者使用android:layout_marginTop="10dp"等方法。但是增加View违背了我们的初衷,并且影响性能。使用过多的margin其实会影响代码的可读性。
这时你就可以使用Space,他是一个轻量级的。
<Space
android:layout_width="match_parent"
android:layout_height="30dp"
/>
其他参考
http://blog.csdn.net/lmj623565791/article/details/45556391
http://www.lightskystreet.com/2015/01/19/android-layout-optimize