如何优化Android layout(UI)性能
来源:互联网 发布:windows repair怎么用 编辑:程序博客网 时间:2024/05/02 20:11
在Android layout中的各种问题一直是让人很头疼。其中,我们只要稍微不留神,自己设计的layout在性能上的表现总会不尽人意。
悲剧回顾:
记得之前有一个项目,前期的layout设计几乎到处都是里三层外三层的各种嵌套。这样的布局实现效果与美工的效果图虽然相差无几,但到了后期,令人难以接受的悲剧发生了——一些配置较低的手机只要运行在layout嵌套较深的界面上,总会出现卡顿现象,若有输入控件,激活输入法时,也会引起程序crash……
悲剧之由来:
我们得始终坚信:有果必有因。
1. 初学时养成的潜意识:不考虑性能,先看效果。大家可能是这样学习的,想快点掌握其实现方法,性能或优化等方面的问题,留着以后再考虑。可是,何时才是“以后”呢?
2. 没有深入理解各种layout运用:怎么方便就怎么来,例如使用LinearLayout进行多层嵌套即可轻松实现复杂的布局。
3. 没太留意用户体验感受:随着时间推移,手机配置越来越高,人们已经很难从感知上去判别layout的加载速度会带来什么样的体验。有时候,即使能感觉到有一点点的有问题,也会轻易放过自己:没关系。
4. 有意识,但不熟悉优化:有时候知道会有问题,但不知道如何判断其优劣,不清楚如何下手,缺少思路与方法等。
Layout优化大致思路:
1. 尽可能消耗较少的系统资源:包括时间,内存,电量等。
2. 尽可能流畅,不给人卡顿,加载慢,等待时间过长,干等无操作的尴尬体验等。
如何对症下药?
我们大概清楚上述的因果后,就得对具体案例进行对症下药,加深理解,进而举一反三。这回我们不能为所欲为了!
那么如何优化呢?下面是一个简单的例子,演示优化步骤及思路:
1. 优化前的一个3层级的layout:
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/LinearLayout1"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
android:paddingBottom=
"@dimen/activity_vertical_margin"
android:paddingLeft=
"@dimen/activity_horizontal_margin"
android:paddingRight=
"@dimen/activity_horizontal_margin"
android:paddingTop=
"@dimen/activity_vertical_margin"
>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center"
>
<TextView
android:id=
"@+id/account"
android:layout_width=
"wrap_content"
android:layout_height=
"60dp"
android:gravity=
"center_vertical"
android:text=
"账号:"
/>
<EditText
android:id=
"@+id/accountInput"
android:layout_width=
"200dp"
android:layout_height=
"60dp"
android:gravity=
"center_vertical"
android:hint=
"请输入账号"
/>
</LinearLayout>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"60dp"
android:gravity=
"center"
>
<TextView
android:id=
"@+id/pwd"
android:layout_width=
"wrap_content"
android:layout_height=
"60dp"
android:gravity=
"center_vertical"
android:text=
"密码:"
/>
<EditText
android:id=
"@+id/pwdInput"
android:layout_width=
"200dp"
android:layout_height=
"60dp"
android:gravity=
"center_vertical"
android:hint=
"请输入6位以上的密码"
/>
</LinearLayout>
</LinearLayout>
其实,在手机上运行这个layout,我们的感官并不能觉察到有什么不妥或不好的体验。所以,我们得通过第三方工具Hierarchy View查看其性能参数:
从上图很直观地看到:这是一个4层级的layout;在id为content的节点上读取其性能数据:
Measure:0.562ms
Layout:0.287ms
Draw:2.212ms
同时,也计算了一下setContentView(R.layout.nested_layout)的时间:42ms
06
-16
15:
21:
35.869:
D/MainActivity(
4739
): setContentView(R.layout.nested_layout), takeTime:
42
ms
计算代码如下:
private
static
final String TAG =
"MainActivity"
;
private long start =
0
;
private long takeTime =
0
;
@Override
protected void onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
start = System.currentTimeMillis();
setContentView(R.layout.nested_layout);
takeTime = System.currentTimeMillis() - start;
Log.d(TAG,
"setContentView(R.layout.nested_layout), takeTime:"
+ takeTime +
"ms"
);
}
就是这么一个简单的UI布局,上面的性能指示器就有3个为红色,暂且(在没有对比之前)认为效果并不是很好。
具体分析:
1. 这里使用了3个容器(LinearLayout),都是用于控制子元素的显示方向;
2. 想想上面的优化思路,尽可能减少时间,内存的开销:在实现同样效果的情况下,容器越多,加载实例化容器,计算,布局,绘制的操作相应地会消耗更多的时间与内存。
3. 如果我们使用较少的容器实现一样的效果,这不就是优化性能了吗?
4. 我们的RelativeLayout不就可以做得到吗?
2. 采用RelateLayout优化后的layout
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/LinearLayout1"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
android:paddingBottom=
"@dimen/activity_vertical_margin"
android:paddingLeft=
"@dimen/activity_horizontal_margin"
android:paddingRight=
"@dimen/activity_horizontal_margin"
android:paddingTop=
"@dimen/activity_vertical_margin"
>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center"
>
<TextView
android:id=
"@+id/account"
android:layout_width=
"wrap_content"
android:layout_height=
"60dp"
android:layout_alignParentLeft=
"true"
android:gravity=
"center_vertical"
android:text=
"账号:"
/>
<EditText
android:id=
"@+id/accountInput"
android:layout_width=
"200dp"
android:layout_height=
"60dp"
android:layout_toRightOf=
"@id/account"
android:gravity=
"center_vertical"
android:hint=
"请输入账号"
/>
<TextView
android:id=
"@+id/pwd"
android:layout_width=
"wrap_content"
android:layout_height=
"60dp"
android:layout_below=
"@id/account"
android:gravity=
"center_vertical"
android:text=
"密码:"
/>
<EditText
android:id=
"@+id/pwdInput"
android:layout_width=
"200dp"
android:layout_height=
"60dp"
android:layout_below=
"@id/accountInput"
android:layout_toRightOf=
"@id/pwd"
android:gravity=
"center_vertical"
android:hint=
"请输入6位以上的密码"
/>
</RelativeLayout>
</LinearLayout>
同样使用工具查看:
很明显,我们减少了一个容器,其中的2个LinearLayout被一个RelateLayout代替,性能指示器也没有出现红色。在同样的节点处性能参数如下:
Measure:0.443ms
Layout:0.060ms
Draw:1947ms
同样,计算setContentView(R.layout.optimized_layout)花费的时间:36ms
各指标都比原来提高了。
事情还没完,是不是总觉得夹在FrameLayout与RelateLayout之间的LinearLayout有点多余呢?我RelateLayout干嘛要经过你LinearLayout呢,如果真的非要经过你,你能说说你在这里的有用之处吗?
3. 去除没必要层级:
再请来一个大神对第2步的layout进行检查与评判——Lint:
从上图红圈中的提示内容可知:id为LinearLayout1的容器是没有必要存在的。所以这次的优化得去掉这没必要的层级。
<RelativeLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:gravity=
"center"
android:paddingBottom=
"@dimen/activity_vertical_margin"
android:paddingLeft=
"@dimen/activity_horizontal_margin"
android:paddingRight=
"@dimen/activity_horizontal_margin"
android:paddingTop=
"@dimen/activity_vertical_margin"
>
<TextView
android:id=
"@+id/account"
android:layout_width=
"wrap_content"
android:layout_height=
"60dp"
android:layout_alignParentLeft=
"true"
android:gravity=
"center_vertical"
android:text=
"账号:"
/>
<EditText
android:id=
"@+id/accountInput"
android:layout_width=
"200dp"
android:layout_height=
"60dp"
android:layout_toRightOf=
"@id/account"
android:gravity=
"center_vertical"
android:hint=
"请输入账号"
/>
<TextView
android:id=
"@+id/pwd"
android:layout_width=
"wrap_content"
android:layout_height=
"60dp"
android:layout_below=
"@id/account"
android:gravity=
"center_vertical"
android:text=
"密码:"
/>
<EditText
android:id=
"@+id/pwdInput"
android:layout_width=
"200dp"
android:layout_height=
"60dp"
android:layout_below=
"@id/accountInput"
android:layout_toRightOf=
"@id/pwd"
android:gravity=
"center_vertical"
android:hint=
"请输入6位以上的密码"
/>
</RelativeLayout>
再看层级图:
清楚地看到,性能指示器一片绿,相比于优化前:我们原来需要解掉3件“衣服”,现在只需要解掉一件就可以看到你想要的,你说这速度能不快吗?到此,前面的暂且可以去掉了!
小结:
1. 性能指示器,优化layout的参考方向。
2. 有效利用Lint工具,进行优化,他不仅仅应用于layout的优化,还包括code的优化,总之其功能非常强大!
- 如何优化Android layout(UI)性能
- Android性能优化(二),Layout布局优化
- Android UI性能优化
- android UI性能优化
- Android UI性能优化
- Android 性能优化 UI优化
- Android-性能优化-UI优化
- Android性能优化--Layout优化篇
- Android UI 优化 [ 类别:Layout ] #1
- Android UI 优化 [ 类别:Layout ] #2
- Android UI 优化 [ 类别:Layout ] #3
- Android UI 优化 [ 类别:Layout ] #1
- Android UI性能优化(一)
- Android UI性能优化(二)
- Android UI性能优化(三)
- Android UI性能优化(渲染)
- Android性能优化-UI性能优化
- android UI性能优化(4)--如何去避免ANR
- FileHelper-文件操作辅助类
- MD5加密登录密码的用
- min stack
- struts2上传照片成功并显示,但是工程文件夹下没有
- Oraclev事务的四大属性
- 如何优化Android layout(UI)性能
- 根据地址返回经纬度(使用百度地图API)
- [C/C++] free()函数和iOS release--(重点free函数)整理汇总
- virtualbox崩溃一例
- RSA加/解密算法——gmp大数库C++实现
- 【Linux 内核】内存管理(二)伙伴算法
- DbHelper-SQL数据库访问助手
- K近邻法(KNN)
- JSP动作标识