`
阅读更多

最新最准确内容建议直接访问原文:Android性能优化之布局优化

本文为Android性能优化的第二篇——布局优化,主要介绍使用抽象布局标签(include, viewstub, merge)、去除不必要的嵌套和View节点、减少不必要的infalte及其他Layout方面可调优点,顺带提及布局调优相关工具(hierarchy viewer和lint)
1、抽象布局标签
(1) <include>标签
include标签常用于将布局中的公共部分提取出来供其他layout共用,以实现布局模块化,这在布局编写方便提供了大大的便利。
下面以在一个布局main.xml中用include引入另一个布局foot.xml为例。main.mxl代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/simple_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="@dimen/dp_80" />

    <include layout="@layout/foot.xml" />

</RelativeLayout>

其中include引入的foot.xml为公用的页面底部,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_above="@+id/text"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_alignParentBottom="true"
        android:text="@string/app_name" />

</RelativeLayout>

<include>标签唯一需要的属性是layout属性,指定需要包含的布局文件。可以定义android:id和android:layout_*属性来覆盖被引入布局根节点的对应属性值。注意重新定义android:id后,子布局的顶结点i就变化了。

 

(2) <viewstub>标签
viewstub标签同include标签一样可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。
viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。
下面以在一个布局main.xml中加入网络错误时的提示页面network_error.xml为例。main.mxl代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    ……
    <ViewStub
        android:id="@+id/network_error_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/network_error" />

</RelativeLayout>

其中network_error.xml为只有在网络错误时才需要显示的布局,默认不会被解析,示例代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/network_setting"
        android:layout_width="@dimen/dp_160"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/network_setting" />

    <Button
        android:id="@+id/network_refresh"
        android:layout_width="@dimen/dp_160"
        android:layout_height="wrap_content"
        android:layout_below="@+id/network_setting"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/dp_10"
        android:text="@string/network_refresh" />

</RelativeLayout>


在java中通过(ViewStub)findViewById(id)找到ViewStub,通过stub.inflate()展开ViewStub,然后得到子View,如下:

private View networkErrorView;

private void showNetError() {
    // not repeated infalte
    if (networkErrorView != null) {
        networkErrorView.setVisibility(View.VISIBLE);
        return;
    }

    ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
    networkErrorView = stub.inflate();
    Button networkSetting = (Button)networkErrorView.findViewById(R.id.network_setting);
    Button refresh = (Button)findViewById(R.id.network_refresh);
}

private void showNormal() {
    if (networkErrorView != null) {
        networkErrorView.setVisibility(View.GONE);
    }
}

在上面showNetError()中展开了ViewStub,同时我们对networkErrorView进行了保存,这样下次不用继续inflate。这就是后面第三部分提到的减少不必要的infalte。

viewstub标签大部分属性同include标签类似。

 

上面展开ViewStub部分代码

ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
networkErrorView = stub.inflate();

也可以写成下面的形式

View viewStub = findViewById(R.id.network_error_layout);
viewStub.setVisibility(View.VISIBLE);   // ViewStub被展开后的布局所替换
networkErrorView =  findViewById(R.id.network_error_layout); // 获取展开后的布局

效果一致,只是不用显示的转换为ViewStub。通过viewstub的原理我们可以知道将一个view设置为GONE不会被解析,从而提高layout解析速度,而VISIBLE和INVISIBLE这两个可见性属性会被正常解析。

 

(3) <merge>标签
在使用了include后可能导致布局嵌套过多,多余不必要的layout节点,从而导致解析变慢,不必要的节点和嵌套可通过hierarchy viewer(下面布局调优工具中有具体介绍)或设置->开发者选项->显示布局边界查看。

 

merge标签可用于两种典型情况:
a.  布局顶结点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity内容试图的parent view就是个FrameLayout,所以可以用merge消除只剩一个。
b.  某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自动被忽略,而将其子节点全部合并到主布局中。

以(1) <include>标签的示例为例,用hierarchy viewer查看main.xml布局如下图:


可以发现多了一层没必要的RelativeLayout,将foot.xml中RelativeLayout改为merge,如下:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_above="@+id/text"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:layout_alignParentBottom="true"
        android:text="@string/app_name" />

</merge>

运行后再次用hierarchy viewer查看main.xml布局如下图:

这样就不会有多余的RelativeLayout节点了。

 

2、去除不必要的嵌套和View节点

更多调优方式及调优工具介绍见原文:Android性能优化之布局优化

 

你可能还感兴趣:

Android性能调优

Android性能优化之数据库优化

Android 图片内存缓存

Android 图片SD卡缓存

Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)

分享到:
评论

相关推荐

    Android性能优化.pdf

    【Android性能优化】是Android开发中的重要环节,涵盖了多个关键领域,包括ANR问题解析、crash监控方案、启动速度与执行效率优化、内存优化、耗电优化、网络传输与数据存储优化以及APK大小优化。 **ANR问题解析**是...

    布局优化Demo

    在Android开发中,布局优化是提高应用性能和用户体验的关键因素之一。"布局优化Demo"着重展示了如何通过合理使用`include`、`merge`和`ViewStub`来优化Android界面的布局文件,从而达到减少资源消耗、加快加载速度的...

    面试Android性能优化

    本专题将深入探讨Android性能优化的关键知识点,帮助开发者提升应用的运行效率和用户体验。 首先,我们要理解Android性能优化的基本原则:减少资源消耗、提高响应速度、降低内存占用以及提升电池续航。在Java编程...

    Android性能优化典范 - 第6季 - 胡凯1

    【Android性能优化典范 - 第6季 - 胡凯】主要涵盖了Android应用性能优化的关键方面,特别是关于程序启动时间和安装包大小的优化。以下是详细的知识点解析: 1. **程序启动时间优化**: - **启动时间的重要性**:...

    免费:Android性能优化视频百度云下载链接.rar

    这个"免费:Android性能优化视频百度云下载链接.rar"的压缩包文件提供了一个学习资源,可能是由一系列视频教程组成,帮助开发者深入理解和掌握Android应用的性能调优技巧。虽然没有直接提供视频内容,但包含的"免费...

    android 性能优化-Systrace分析UI性能demo

    在Android开发中,性能优化是提升用户体验的关键环节...总之,Systrace是Android性能优化的得力助手,它为开发者提供了深入了解系统行为的途径。通过深入分析和优化UI相关事件,我们能够显著提升应用的性能和用户体验。

    Android应用性能优化.pdf

    根据提供的文件信息,“Android应用性能优化.pdf”这一文档主要聚焦于Android应用的性能优化方法与实践。虽然部分内容涉及社群推广信息,并未直接提供具体的性能优化技术细节,但我们可以通过标题及描述推断出文档的...

    《Android应用性能优化》

    总的来说,《Android应用性能优化》是一本全面讲解Android性能提升的指南,它可以帮助开发者构建更加高效、稳定和用户友好的应用程序。虽然技术日新月异,但基本的优化原则和技巧依然有效,对于任何Android开发者来...

    Android 性能优化之UI优化源码

    配合博客文章《Android性能优化之UI优化源码》(链接:https://www.cnblogs.com/Oztaking/p/9350295.html),读者可以更深入地了解UI优化的具体实践和源码解析。通过理解和运用上述知识点,开发者能够打造出流畅、...

    android 性能优化文章

    Android性能优化是一个涵盖广泛的主题,涉及到系统层面的优化、内存管理、UI绘制、启动速度提升等多个方面。以下是对标题和描述中涉及的知识点的详细解释: 1. **基本概念**:了解Android性能优化,首先要掌握...

    Android 布局优化

    在Android应用开发中,布局优化是提升应用性能和用户体验的关键环节。有效的布局优化可以减少内存消耗,加快界面渲染速度,并提高应用的响应性。本文将深入探讨如何利用`include`、`ViewStub`和`merge`标签进行...

    android应用性能优化最佳实践读书笔记

    在Android应用开发中,性能优化是一项至关重要的任务,它直接影响到用户的体验和应用程序的市场竞争力。"Android应用性能优化最佳实践"这本书深入探讨了如何提升Android应用的性能,以下是一些核心知识点的总结: 1...

    Android性能优化最佳实践(png图)

    布局优化,绘制优化,内存优化,启动优化,其他,稳定,省电优化,体积优化等

    Android应用性能优化经验分享-张明云

    因此,性能优化成为了提升用户体验的关键因素之一。性能不佳的应用不仅会导致用户体验下降,还会增加电量消耗、降低设备运行效率,甚至可能导致用户的流失。 ### 性能优化的重要性 1. **改善用户体验**:优化后的...

    android 360°全方面性能调优.pdf

    《Android 360°全方面性能调优》是一本深度探讨Android系统性能优化的宝典,涵盖了设计思想、代码优化、程序性能、内存管理、功耗控制、网络通信、应用打包、屏幕适配、启动速度、流畅度、ANR问题、崩溃监控、OOM...

    Android性能优化篇 [ 谷歌官方 ]-102116321

    Android性能优化是开发高质量应用程序的关键,尤其是在资源有限的移动设备上。谷歌官方推出的Android性能优化系列视频,旨在帮助开发者创建更快速、更高效的App。本篇文章将概述其中的一些核心概念,包括渲染性能、...

    Android开发的性能优化.pdf

    "Android开发的性能优化" ...通过选择合适的数据类型、汇编执行的优化、CPU的优化、内存布局的优化、性能优化的方法、Android系统的性能优化和应用程序的性能优化等,可以提高Android应用程序的性能和用户体验。

    Android性能优化系列之内存优化

    内存的分配是由程序完成的,而内存的释放是由垃圾收集器(GarbageCollection,GC)完成的,程序员不需要通过调用函数来释放内存,但也随之带来了内存泄漏的可能,上篇博客,我介绍了Android性能优化系列之布局优化,本...

Global site tag (gtag.js) - Google Analytics