Android布局优化
Android影响布局性能主要是Overdraw(过度绘制),表现在重叠不可见元素的重复绘制会产生额外的开销。
Overdraw以颜色划分等级:蓝色:Overdraw1倍;绿色:Overdraw2倍;浅红:Overdraw3倍;暗红;Overdraw4倍以上(需要进行优化)。
Android布局优化解决措施:
1、合理选择控件
LinearLayout简单易用,效率高,但是使用范围有限。
RelativeLayout较复杂,使用范围广,效率稍差。
2、去掉windows默认背景
去掉window的背景可以在onCreate()中setContentView()之后调用 getWindow().setBackgroundDrawable(null);或者在theme中添加
android:windowbackground="null";
3、去掉不必要的背景
如果子View宽度mach_parent,可以看到完全覆盖了Layout的一部分,这里就可以通过分别设置背景来减少重绘。再比如如果采用的是selector的背景,将normal状态的color设置为“@android:color/transparent",也同样可以解决问题。
4、ClipRect & QuickReject
我们可以通过canvas.clipRect()来帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。这个API可以很好的帮助那些有多组重叠组件的自定义View来控制显示的区域。同时clipRect方法还可以帮助节约CPU与GPU资源,在clipRect区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制。除了clipRect方法之外,我们还可以使用canvas.quickreject()来判断是否没和某个矩形相交,从而跳过那些非矩形区域内的绘制操作。
<ViewStub android:id="@+id/stub_view" android:inflatedId="@+id/panel_stub" android:layout="@layout/progress_overlay" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" />
当你想加载布局时,可以使用下面其中一种方法:
((ViewStub) findViewById(R.id.stub_view)).setVisibility(View.VISIBLE);
View importPanel = ((ViewStub) findViewById(R.id.stub_view)).inflate();
6、Merge
作用:干掉一个VIew层级。
有两种情况下我们可以使用Merge标签来做容器控件。第一种子视图不需要指定任何针对父视图的布局属性,就是说父容器仅仅是个容器,子视图只需要直接添加到父视图上用于显示就行。另外一种是假如需要在LinearLayout里面嵌入一个布局(或者视图),而恰恰这个布局(或者视图)的根节点也是LinearLayout,这样就多了一层没有用的嵌套,无疑这样只会拖慢程序速度。而这个时候如果我们使用merge根标签就可以避免那样的问题。另外Merge只能作为XML布局的根标签使用,当Inflate以<merge />开头的布局文件时,必须指定一个父ViewGroup,并且必须设定attachToRoot为true。
优化方案: 将背景drawable制作成draw9patch,并且将和前景重叠的部分设置为透明。由于Android的2D渲染器会优化draw9patch中的透明区域,从而优化了这次overdraw。 但是背景图片必须制作成draw9patch才行,因为Android 2D渲染器只对draw9patch有这个优化,否则,一张普通的Png,就算你把中间的部分设置成透明,也不会减少这次overdraw。
如果一定做Alpha转化的话,可以采用缓存的方式。
view.setLayerType(LAYER_TYPE_HARDWARE);
doSmoeThing();
view.setLayerType(LAYER_TYPE_NONE);
通过setLayerType方式可以将当前界面缓存在GPU中,这样不需要每次绘制原始界面,但是GPU内存是相当宝贵的,所以用完要马上释放掉。
9、避免“OverDesign”
参考文献:http://www.jianshu.com/p/145fc61011cd