当前位置: 首页 > news >正文

布局性能优化:安卓开发者不可错过的性能优化技巧

作者:麦客奥德彪

当我们开发Android应用时,布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验,使应用更加流畅、响应更加迅速,而低效的布局则会导致应用的运行变得缓慢,甚至出现卡顿、崩溃等问题,影响用户体验。在开发中,布局优化不仅需要考虑到UI设计的美观性和易用性,还需要关注布局的性能,避免出现因视图过多、嵌套过深、图片过大等问题导致的性能瓶颈。通过对布局进行优化,可以显著提高应用的性能和用户体验,减少应用的CPU和内存占用,加快应用的启动和响应速度,降低应用的耗电量,从而提高应用的稳定性和可靠性。

布局性能优化对于提高Android应用的质量和竞争力是至关重要的。在实际开发中,我们需要根据具体的业务场景和设计要求,结合布局优化的最佳实践,逐步提升应用的布局性能,为用户带来更好的体验。

布局为什么会有性能问题呢

那需要了解一下Android View的渲染机制,Android渲染机制是指Android系统中用于显示界面的工作流程。它包括视图树的构建、测量、布局和绘制四个过程。

他们的大致流程是

  1. 构建视图树(View Hierarchy):在应用启动时,Android系统会根据布局文件中定义的View、ViewGroup和其他组件创建一个视图树。视图树是根据xml进行解析的。
  2. 测量(Measure):在测量过程中,系统会遍历视图树,并计算每个视图的大小和位置
  3. 布局(Layout):在布局过程中,系统会根据视图树中每个视图的测量结果,确定每个视图的大小和位置,并将其放置在正确的位置上
  4. 绘制(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。这种操作会导致内存消耗过高的。

常见的检测布局性能工具

  1. Hierarchy Viewer工具:Hierarchy Viewer工具可以帮助开发者分析应用程序的视图层次结构,找出可能存在的性能问题。在Hierarchy Viewer中,可以查看应用程序的视图层次结构,以及每个视图的绘制时间、测量时间和布局时间等性能指标。
  2. TraceView工具:TraceView工具可以帮助开发者分析应用程序的性能问题,包括布局性能问题。在TraceView中,可以查看应用程序的方法调用链和执行时间等信息,以及每个方法的CPU使用率、内存消耗等性能指标。
  3. UI性能分析器:Android Studio中内置了UI性能分析器,可以帮助开发者分析应用程序的UI性能问题,包括布局性能问题。在UI性能分析器中,可以查看应用程序的渲染时间、FPS、布局时间等性能指标,并根据性能指标分析应用程序的性能问题。
  4. 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

  1. 开机Init 进程
  2. 开机启动 Zygote 进程
  3. 开机启动 SystemServer 进程
  4. Binder 驱动
  5. AMS 的启动过程
  6. PMS 的启动过程
  7. Launcher 的启动过程
  8. Android 四大组件
  9. Android 系统服务 - Input 事件的分发过程
  10. Android 底层渲染 - 屏幕刷新机制源码分析
  11. Android 源码分析实战

相关文章:

布局性能优化:安卓开发者不可错过的性能优化技巧

作者&#xff1a;麦客奥德彪 当我们开发Android应用时&#xff0c;布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验&#xff0c;使应用更加流畅、响应更加迅速&#xff0c;而低效的布局则会导致应用的运行变得缓慢&#xff0c;甚至出现卡顿、崩溃等问题&…...

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&#xff1a;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的机器&#xff1a;iptables为空&#xff0c;且每个链路的默认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 中&#xff0c;交叉编译指的是在同一台机器上生成针对不同操作系统或硬件架构的二进制文件。这在开发跨平台应用或构建特定平台的发布版本时非常有用。 交叉编译 Golang 程序的基本步骤如下&#xff1a; 指定目标操作系统和工具链并设置对应的…...

Python中的诡异事:不可见字符!

文章目录 前言1. 起因2. 调查3. 高能4. 释惑 前言 今天分享一件很诡异的事情&#xff0c;我写代码的时候遇到了不可见的字符&#xff01;&#xff01;&#xff01; 1. 起因 今天在使用pipreqs导出项目中所依赖的库时突然报错了&#xff1a; pipreqs . --encodingutf-8 --forc…...

【uniapp】uniapp使用微信开发者工具制作骨架屏:

文章目录 一、效果&#xff1a;二、过程&#xff1a; 一、效果&#xff1a; 二、过程&#xff1a; 【1】微信开发者工具打开项目&#xff0c;生成骨架屏&#xff0c;将wxml改造为vue页面组件&#xff0c;并放入样式 【2】页面使用骨架屏组件 【3】改造骨架屏&#xff08;去除…...

【UE4 RTS】06-Camera Edge Scroll

前言 本篇实现的效果是当玩家将鼠标移至屏幕边缘时&#xff0c;视野会相应的上下左右移动 效果 步骤 1. 打开玩家控制器“RTS_PlayerController_BP”&#xff0c;在类默认值中设置如下选项 新建一个宏&#xff0c;命名为“EdgeSroll”&#xff0c; 添加两个输入和三个输出&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等等关联式容器&#xff0c;它们的底层是红黑树进行模拟实现的&#xff0c;在查询时效率可达到 l o g 2 N log_2 N log2​N&#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点…...

MySQL随心记第二篇

一、正则表达式篇&#xff1a; regular expression--> regexp 元字符: . : 单个的任意字符&#xff08;默认不包含换行&#xff09; \d:数字: 0-9 补集:\D \w:ascil:数字&#xff0c;大写字母&#xff0c;小写字母&#xff0c;以及下划线 unicode: 数字&#xff0c;大…...

0001nginx简介、相关模型与原理

文章目录 一. 什么是Nginx二. ngnix的一些模型1、nginx的进程模型2、worker的抢占&#xff08;锁&#xff09;机制模型3. nginx事件处理模型 三. nginx加载静态资源的过程 一. 什么是Nginx Nginx是一个高性能HTTP反向代理服务器&#xff0c;以下是nginx的相关能力 反向代理&am…...

elasticsearch简单入门语法

基本操作 创建不同的分词器 ik_smart&#xff1a; 极简分词 &#xff1b; ik_max_word: 最细力再度分词 基本的rest命令 methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档&#xff08;指定文档id&#xff09;POSTlocalhost:9200/索引名称/类型名称创建文…...

Python自动化测试用例:如何优雅的完成Json格式数据断言

目录 前言 直接使用 优化 封装 小结 进阶 总结 资料获取方法 前言 记录Json断言在工作中的应用进阶。 直接使用 很早以前写过一篇博客&#xff0c;记录当时获取一个多级json中指定key的数据&#xff1a; #! /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…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...

怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)

+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...