遵循Android Layout优化的两段通用代码

来源:互联网 发布:淘宝福利群真的假的 编辑:程序博客网 时间:2024/06/05 16:21

四个小Tip:

1.尽量不要使用Linelayout,使用Relativelayout替换。android:layout_alignWithParentIfMissing只对Relativelayout有用,如果那个视图设置为gone,这个属性将按照父视图进行调整。

2.对于使用Adapter的控件,如List,使用递归太深的布局,会严重影响性能。 

3.对于Textview和Imageview组成的Layout,直接使用Textview替换(DrawableTop类似属性)。 

4.对于父Layout是FrameLayout的,如果子Layout也是FrameLayout,可以将FrameLayout替换为merge,这样可以减少一层递归深度。


其中一个就是关于Layout的优化就是关于:<merge/>标签在UI界面中的优化作用,跳转过去看看就好了。


如何优化Android layout(UI)性能


悲剧回顾:

记得之前有一个项目,前期的layout设计几乎到处都是里三层外三层的各种嵌套。这样的布局实现效果与美工的效果图虽然相差无几,但到了后期,令人难以接受的悲剧发生了——一些配置较低的手机只要运行在layout嵌套较深的界面上,总会出现卡顿现象,若有输入控件,激活输入法时,也会引起程序crash……


悲剧之由来:

我们得始终坚信:有果必有因。

1. 初学时养成的潜意识:不考虑性能,先看效果。大家可能是这样学习的,想快点掌握其实现方法,性能或优化等方面的问题,留着以后再考虑。可是,何时才是“以后”呢?

2. 没有深入理解各种layout运用:怎么方便就怎么来,例如使用LinearLayout进行多层嵌套即可轻松实现复杂的布局。

3. 没太留意用户体验感受:随着时间推移,手机配置越来越高,人们已经很难从感知上去判别layout的加载速度会带来什么样的体验。有时候,即使能感觉到有一点点的有问题,也会轻易放过自己:没关系。

4. 有意识,但不熟悉优化:有时候知道会有问题,但不知道如何判断其优劣,不清楚如何下手,缺少思路与方法等。


Layout优化大致思路:

1. 尽可能消耗较少的系统资源:包括时间,内存,电量等。

2. 尽可能流畅,不给人卡顿,加载慢,等待时间过长,干等无操作的尴尬体验等。


如何对症下药?

我们大概清楚上述的因果后,就得对具体案例进行对症下药,加深理解,进而举一反三。这回我们不能为所欲为了!

那么如何优化呢?下面是一个简单的例子,演示优化步骤及思路:

1. 优化前的一个3层级的layout:

<LinearLayoutxmlns: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-1615:21:35.869:D/MainActivity(4739): setContentView(R.layout.nested_layout), takeTime:42ms
计算代码如下:

private static final String TAG = "MainActivity";private long start = 0;private long takeTime = 0;@Overrideprotected 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

<LinearLayoutxmlns: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的容器是没有必要存在的。所以这次的优化得去掉这没必要的层级。

<RelativeLayoutxmlns: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"><TextViewandroid:id="@+id/account"android:layout_width="wrap_content"android:layout_height="60dp"android:layout_alignParentLeft="true"android:gravity="center_vertical"android:text="账号:"/><EditTextandroid:id="@+id/accountInput"android:layout_width="200dp"android:layout_height="60dp"android:layout_toRightOf="@id/account"android:gravity="center_vertical"android:hint="请输入账号"/><TextViewandroid:id="@+id/pwd"android:layout_width="wrap_content"android:layout_height="60dp"android:layout_below="@id/account"android:gravity="center_vertical"android:text="密码:"/><EditTextandroid: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的优化,总之其功能非常强大!




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大学档案学年测评有涂改痕迹怎么办 驼背怎么办要能快速矫正的方法 手臂往后扭后手臂根部疼又肿怎么办 一岁四个月宝宝有点斜颈怎么办? 六个月的宝宝脖子有点歪怎么办 情感交叉擦腿综合症心里治疗怎么办 坐月子受风了胳膊腿疼怎么办 劲椎手术两个月双腿疼痛麻这怎么办 手机里存的照片删除了怎么办 买了好几双鞋子都不防滑怎么办 电脑平车车加绒过厚不起线怎么办 碰见那种看不起人的店员应该怎么办 在食品厂上班載卫生帽头发痒怎么办 工司没给员工上保险离职后怎么办 货物被香港律政司扣了怎么办 室友考研要跟我考一样的学校怎么办 药流第一天才吃了一粒米非司怎么办 药流半月同房第二天大出血怎么办 口臭想让它变得不臭怎么办 来单位干了几天不满意想离职怎么办 药流吃药期间吃什么吐什么怎么办 养狗家里味道大怎么办养花有用吗 第一天上班站的脚疼怎么办 入职没有人事所需要的证书怎么办 入职第一天后不想去了怎么办 警察在执法过程中殴打群众怎么办 肾结石打了3天针痛得厉害怎么办 征兵体检过了到部队退兵怎么办 圆通快递要求退回结果被签收怎么办 新生儿蛋蛋淹了破皮了怎么办 要是和同学玩的时候打到睾丸怎么办 睾丸撞了一下里面碎了怎么办 睾丸被蚊子咬了挠坏流水疼怎么办 沐浴乳大量的灌注到尿道里怎么办 当电脑显示有文件损害时怎么办? 电脑上的压缩包手机上打不开怎么办 第五人格多酷账号退出了怎么办 更新显卡驱动时屏幕关闭了怎么办 不知道杯孕做了两次C丁怎么办 小说签约后更不到要求的字数怎么办 电脑中了感染病毒杀不干净怎么办