布局性能优化:安卓开发者不可错过的性能优化技巧
作者:麦客奥德彪
当我们开发Android应用时,布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验,使应用更加流畅、响应更加迅速,而低效的布局则会导致应用的运行变得缓慢,甚至出现卡顿、崩溃等问题,影响用户体验。在开发中,布局优化不仅需要考虑到UI设计的美观性和易用性,还需要关注布局的性能,避免出现因视图过多、嵌套过深、图片过大等问题导致的性能瓶颈。通过对布局进行优化,可以显著提高应用的性能和用户体验,减少应用的CPU和内存占用,加快应用的启动和响应速度,降低应用的耗电量,从而提高应用的稳定性和可靠性。
布局性能优化对于提高Android应用的质量和竞争力是至关重要的。在实际开发中,我们需要根据具体的业务场景和设计要求,结合布局优化的最佳实践,逐步提升应用的布局性能,为用户带来更好的体验。
布局为什么会有性能问题呢
那需要了解一下Android View的渲染机制,Android渲染机制是指Android系统中用于显示界面的工作流程。它包括视图树的构建、测量、布局和绘制四个过程。
他们的大致流程是

- 构建视图树(View Hierarchy):在应用启动时,Android系统会根据布局文件中定义的View、ViewGroup和其他组件创建一个视图树。视图树是根据xml进行解析的。
- 测量(Measure):在测量过程中,系统会遍历视图树,并计算每个视图的大小和位置
- 布局(Layout):在布局过程中,系统会根据视图树中每个视图的测量结果,确定每个视图的大小和位置,并将其放置在正确的位置上
- 绘制(Draw):在绘制过程中,系统会遍历视图树,并将每个视图绘制到屏幕上
在这几个过程中,布局过程是比较耗费时间的,并且耗时与视图树的复杂程度成正比。
复杂的布局指的是树关系的复杂,而不是元素的复杂。
不一样的角度
从系统角度分析,Android系统的UI界面是基于视图层次结构(View Hierarchy)构建的,每个UI元素都是View或ViewGroup对象的实例,这些对象按照它们在界面中出现的顺序排列,构成了一个视图层次结构。在这个结构中,每个UI元素都有自己的父元素和子元素,因此构成了一个树形结构。这个树形结构的根节点是一个ViewGroup对象,它是整个视图层次结构的根。
当用户进行交互操作时,Android系统需要对视图层次结构进行更新,例如重新布局、重绘等操作,这些操作会消耗大量的CPU和内存资源。因此,视图层次结构的构建对应用程序的性能和响应速度至关重要。
常见布局解析,用对了,你的性能问题会减少很多
我们从开始学习Android就知道五大布局是Android的布局基础,大家还记得他们的优缺点吗?之所以有五大布局,就是因为他们使用场景各不相同,然而有时候写法就是上来就相对,别的不考虑,这正确吗?
这是一个对比表格,加颜色的,年龄小的程序员可能都不知道。

通过这个对比,你会发现,每一个布局都有它的用途,要是用对了,在性能方面都有提升。也不是说用约束布局一撸到底,在有些专场的场景中,对应的布局更加优于约束布局。
回顾完之后,我们看看开发中还有哪些影响性能的写法。
常见的开发中有损布局性能的操作方式
嵌套层数过多
当一个布局容器包含多个子布局容器时,会导致视图层次结构的深度增加,从而增加了CPU和内存资源的消耗
<LinearLayout><RelativeLayout></RelativeLayout><LinearLayout></LinearLayout>
</LinearLayout>
内存使用过高
当一个布局容器包含大量的子视图时,会导致内存占用过高,从而影响应用程序的性能
<RelativeLayout><ImageView/><ImageView/><ImageView/></RelativeLayout>
不合适的布局容器
在布局中选择合适的布局容器可以避免不必要的布局操作和内存消耗(当需要显示大量的数据列表时,使用ListView或RecyclerView等容器可以避免不必要的视图更新和内存消耗)
过多的重绘操作
当一个布局容器中包含多个视图时,每次修改其中一个视图的属性,都会导致整个布局容器的重绘操作
可以使用ViewStub元素来延迟加载复杂的视图。
不合理的布局属性
在布局中选择合适的布局属性可以避免不必要的视图更新和内存消耗
在使用RelativeLayout布局容器时,它的测量和布局都需要参考父、兄等原则,所以需要考虑到视图的相对位置和大小,以避免不必要的布局操作和内存消耗。
使用无效的布局容器
在布局中使用无效的布局容器会增加不必要的布局操作和内存消耗,影响应用程序的性能和响应速度
<TableLayout><TableRow><TextView/><TextView/></TableRow><TableRow><TextView/><TextView/></TableRow>
</TableLayout>
这种操作在开发中还是比较常见的,有时候为了给Text View或者ImageView 添加点击区域,外边搞一个FragmeLayout。这种操作会导致内存消耗过高的。
常见的检测布局性能工具
- Hierarchy Viewer工具:Hierarchy Viewer工具可以帮助开发者分析应用程序的视图层次结构,找出可能存在的性能问题。在Hierarchy Viewer中,可以查看应用程序的视图层次结构,以及每个视图的绘制时间、测量时间和布局时间等性能指标。
- TraceView工具:TraceView工具可以帮助开发者分析应用程序的性能问题,包括布局性能问题。在TraceView中,可以查看应用程序的方法调用链和执行时间等信息,以及每个方法的CPU使用率、内存消耗等性能指标。
- UI性能分析器:Android Studio中内置了UI性能分析器,可以帮助开发者分析应用程序的UI性能问题,包括布局性能问题。在UI性能分析器中,可以查看应用程序的渲染时间、FPS、布局时间等性能指标,并根据性能指标分析应用程序的性能问题。
- Monkey测试工具:Monkey测试工具可以帮助开发者测试应用程序的稳定性和性能问题,包括布局性能问题。在Monkey测试中,可以模拟用户随机点击和滑动操作,以测试应用程序的稳定性和响应速度,同时可以通过TraceView等工具分析应用程序的性能问题。(提前做好监测的买点,trace收集,然后用monkey测试,最后分析trace)
总结
1.减少布局层次
布局层次越深,绘制所需的时间就越长,因此应该尽可能减少布局层次。可以通过使用 ConstraintLayout 或者自定义 View 来减少布局层次。
2.使用合适的布局容器
应该选择最适合当前布局需求的布局容器,避免使用过于复杂的布局容器,比如 LinearLayout 嵌套多层、RelativeLayout 的多重嵌套等。
3.使用 ViewStub 来延迟加载视图
如果布局中包含复杂的视图,可以考虑使用 ViewStub 来延迟加载这些视图,以减少布局的加载时间。
4.避免使用过多的嵌套布局
嵌套布局会增加布局的复杂度,导致渲染时间变长。因此应该尽量避免过多的嵌套布局。
5.使用合适的布局属性
合理使用布局属性可以让布局更加简洁、高效,比如使用 match_parent 和 wrap_content 来替代具体的像素值。
6.避免在布局文件中使用过多的 include 标签
include 标签可以重复使用布局,但是过多的使用会增加布局层次和渲染时间,因此应该尽量避免在布局文件中使用过多的 include 标签
主要是要弄明白布局的使用场景,从这几个坑出发,写代码的时候上点心。
为了帮助到大家更好的全面清晰的掌握好性能优化,准备了相关的核心笔记(还该底层逻辑):https://qr18.cn/FVlo89
性能优化核心笔记:https://qr18.cn/FVlo89
启动优化

内存优化

UI优化

网络优化

Bitmap优化与图片压缩优化:https://qr18.cn/FVlo89

多线程并发优化与数据传输效率优化

体积包优化

《Android 性能监控框架》:https://qr18.cn/FVlo89

《Android Framework学习手册》:https://qr18.cn/AQpN4J
- 开机Init 进程
- 开机启动 Zygote 进程
- 开机启动 SystemServer 进程
- Binder 驱动
- AMS 的启动过程
- PMS 的启动过程
- Launcher 的启动过程
- Android 四大组件
- Android 系统服务 - Input 事件的分发过程
- Android 底层渲染 - 屏幕刷新机制源码分析
- Android 源码分析实战

相关文章:
布局性能优化:安卓开发者不可错过的性能优化技巧
作者:麦客奥德彪 当我们开发Android应用时,布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验,使应用更加流畅、响应更加迅速,而低效的布局则会导致应用的运行变得缓慢,甚至出现卡顿、崩溃等问题&…...
Python 中的机器学习简介:多项式回归
一、说明 多项式回归可以识别自变量和因变量之间的非线性关系。本文是关于回归、梯度下降和 MSE 系列文章的第三篇。前面的文章介绍了简单线性回归、回归的正态方程和多元线性回归。 二、多项式回归 多项式回归用于最适合曲线拟合的复杂数据。它可以被视为多元线性回归的子集。…...
docker 容器中执行命令出现错误: 13: Permission denied
错误 13: Permission denied [rootVM-32-11-tencentos ~]# docker exec -it kibana1 /bin/bash kibana76c20c215dcb:~$ apt-get install vi E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied) E: Unable to acquire the dpkg frontend…...
JavaWeb学习|JavaBean;MVC三层架构;Filter;Listener
1.JavaBean 实体类 JavaBean有特定的写法: 必须要有一个无参构造 属性必须私有化。 必须有对应的get/set方法 用来和数据库的字段做映射 ORM; ORM:对象关系映射 表--->类 字段-->属性 行记录---->对象 2.<jsp:useBean 标签 3. MVC三层架构 4. Filter …...
arx 外部参照文件(XREF)的添加、删除、卸载和重载_objectarx
添加参照 CString strFileName;int nIndex = strFilePath.ReverseFind(\\);if (nIndex != -1){strFileName = strFilePath.Right(strFilePath....
【博客699】docker daemon预置iptables剖析
docker daemon预置iptables剖析 没有安装docker的机器:iptables为空,且每个链路的默认policy均为ACCEPT [root~]# iptables-save[root ~]# iptables -t raw -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)pkts bytes target prot opt …...
Golang 中的交叉编译详解
Golang 中的交叉编译 在 Golang 中,交叉编译指的是在同一台机器上生成针对不同操作系统或硬件架构的二进制文件。这在开发跨平台应用或构建特定平台的发布版本时非常有用。 交叉编译 Golang 程序的基本步骤如下: 指定目标操作系统和工具链并设置对应的…...
Python中的诡异事:不可见字符!
文章目录 前言1. 起因2. 调查3. 高能4. 释惑 前言 今天分享一件很诡异的事情,我写代码的时候遇到了不可见的字符!!! 1. 起因 今天在使用pipreqs导出项目中所依赖的库时突然报错了: pipreqs . --encodingutf-8 --forc…...
【uniapp】uniapp使用微信开发者工具制作骨架屏:
文章目录 一、效果:二、过程: 一、效果: 二、过程: 【1】微信开发者工具打开项目,生成骨架屏,将wxml改造为vue页面组件,并放入样式 【2】页面使用骨架屏组件 【3】改造骨架屏(去除…...
【UE4 RTS】06-Camera Edge Scroll
前言 本篇实现的效果是当玩家将鼠标移至屏幕边缘时,视野会相应的上下左右移动 效果 步骤 1. 打开玩家控制器“RTS_PlayerController_BP”,在类默认值中设置如下选项 新建一个宏,命名为“EdgeSroll”, 添加两个输入和三个输出&a…...
无涯教程-Perl - length函数
描述 此函数返回EXPR值的长度(以字符为单位),如果未指定,则返回$_。如果要确定相应的大小,请在数组或哈希上使用标量context。 语法 以下是此函数的简单语法- length EXPRlength返回值 此函数返回字符串的大小。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl$o…...
怎样在 CentOS 里下载 RPM 包及其所有依赖包
前几天我尝试去创建一个仅包含我们经常在 CentOS 7 下使用的软件的本地仓库。当然,我们可以使用 curl 或者 wget 下载任何软件包,然而这些命令并不能下载要求的依赖软件包。你必须去花一些时间而且手动的去寻找和下载被安装的软件所依赖的软件包。然而,我们并不是必须这样。…...
在Ubuntu上使用NFS挂载
假设要把192.16.2.101服务器上的 /home/sharedata 挂载到192.16.2.102服务器上的 /home/receive_data 一、服务端 1、安装NFS服务端 sudo apt-get install nfs-kernel-server 2、修改NFS挂载配置文件 sudo vim /etc/exports 在文件中输入 /home/sharedata 192.16.2.102(…...
复现海康威视综合安防管理平台artemis接口Spring boot heapdump内存泄露漏洞
目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现 一、漏洞描述 HIKVISION iSecure Center综合安防管理平台是一套“集成化”、“智能化”的平台,通过接入视频监控、一卡通...
哈希unordered系列介绍(上)
一.Unordered_map,Unordered_set介绍 在之前我们已经介绍过set,map,multiset等等关联式容器,它们的底层是红黑树进行模拟实现的,在查询时效率可达到 l o g 2 N log_2 N log2N,即最差情况下需要比较红黑树的高度次,当树中的节点…...
MySQL随心记第二篇
一、正则表达式篇: regular expression--> regexp 元字符: . : 单个的任意字符(默认不包含换行) \d:数字: 0-9 补集:\D \w:ascil:数字,大写字母,小写字母,以及下划线 unicode: 数字,大…...
0001nginx简介、相关模型与原理
文章目录 一. 什么是Nginx二. ngnix的一些模型1、nginx的进程模型2、worker的抢占(锁)机制模型3. nginx事件处理模型 三. nginx加载静态资源的过程 一. 什么是Nginx Nginx是一个高性能HTTP反向代理服务器,以下是nginx的相关能力 反向代理&am…...
elasticsearch简单入门语法
基本操作 创建不同的分词器 ik_smart: 极简分词 ; ik_max_word: 最细力再度分词 基本的rest命令 methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)POSTlocalhost:9200/索引名称/类型名称创建文…...
Python自动化测试用例:如何优雅的完成Json格式数据断言
目录 前言 直接使用 优化 封装 小结 进阶 总结 资料获取方法 前言 记录Json断言在工作中的应用进阶。 直接使用 很早以前写过一篇博客,记录当时获取一个多级json中指定key的数据: #! /usr/bin/python # coding:utf-8 """ aut…...
阿里云对象存储服务OSS
1、引依赖 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version> </dependency> <dependency><groupId>javax.xml.bind</groupId><artifa…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果,那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
