Android 性能与视图层次结构查看,检查布局性能
ztj100 2024-11-22 00:13 37 浏览 0 评论
对 View 对象层次结构的管理方式会显著影响应用的性能。本页介绍如何评估视图层次结构是否减慢了应用的速度,并且还提供了一些针对可能出现的问题的解决策略。
布局和度量性能
渲染流水线包含“布局和度量”阶段,系统在此阶段以适当的方式将相关项放置在视图层次结构中。此阶段的度量部分确定 View 对象的大小和边界,布局部分确定 View 对象在屏幕上的放置位置。
这两个流水线阶段在处理每个视图或布局时,都会产生少量开销。在大多数情况下,此开销很小,不会明显影响性能。不过,当应用添加或移除 View 对象时(例如在 RecyclerView 对象回收或重用 View 对象时),此开销会变大。如果 View 对象需要考虑调整大小来保持其约束,此开销也会增加:例如,如果您的应用对包围文本的 View 对象调用 SetText(),View 可能需要调整大小。
如果这类操作花费的时间太长,可能会导致帧无法在允许的 16 毫秒内完成渲染,从而造成丢帧并使动画变得粗糙。
由于您无法将这些操作移至工作器线程(您的应用必须在主线程上处理这些操作),因此最好的选择是对它们进行优化,使其花费尽可能少的时间。
管理复杂性:布局很重要
Android 布局允许您将界面对象嵌套在视图层次结构中。这种嵌套也会增加布局开销。当应用处理布局对象时,也会对布局的所有的对象执行相同的处理。对于复杂的布局,有时仅在系统第一次计算布局时才会产生开销。例如,当应用在 RecyclerView 对象中回收复杂的列表项时,系统需要列出所有对象。又如,细微的更改可以往上朝父级传播,直至到达不影响父级大小的对象为止。
布局耗时过长最常见的情况是,View 对象的层次结构互相嵌套。每个嵌套的布局对象都会增加布局阶段的开销。层次结构越扁平,完成布局阶段所需的时间越少。
如果使用 RelativeLayout 类,则可通过使用未设权重的嵌套 LinearLayout 视图,以更低的开销达到同样的效果。此外,如果您的应用面向 Android 7.0(API 级别 24)或更高版本,您可以使用特殊的布局编辑器来创建 ConstraintLayout 对象,而非 RelativeLayout。这样做可以避免本节中讲到的许多问题。ConstraintLayout 类提供类似的布局控制,但性能大大提高。该类使用自己的约束解析系统,采用与标准布局完全不同的方式来解析视图之间的关系。
Double Taxation
通常情况下,框架会在一次遍历中快速执行布局或度量阶段。但在一些情况比较复杂的布局中,在最终放置元素之前,框架可能必须对层次结构中需要多次遍历才能解析的部分执行多次迭代。必须执行不止一次“布局和度量”迭代的情况称为“Double Taxation”。
例如,当您使用 RelativeLayout 容器时(该容器允许您根据其他 View 对象的位置来放置 View 对象),框架会执行以下操作:
- 执行一次“布局和度量”遍历。在此过程中,框架会根据每个子对象的请求计算该子对象的位置和大小。
- 结合此数据和对象的权重确定关联视图的恰当位置。
- 执行第二次布局遍历,以最终确定对象的位置。
- 进入渲染过程的下一个阶段。
视图层次结构的层次越多,潜在的性能损失就越大。
此外,RelativeLayout 以外的容器也可能会导致 Double Taxation。例如:
- 将 LinearLayout 视图设置为水平方向,可能会导致执行双重“布局和度量”遍历。如果您添加 measureWithLargestChild,则垂直方向上也可能会发生双重“布局和度量”变化,因为在这种情况下,框架可能需要执行第二次遍历才能正确解析对象的大小。
- GridLayout 也有类似的问题。虽然该容器也允许相对定位,但它通常会通过预处理子视图之间的位置关系来避免 Double Taxation。不过,如果布局使用权重或使用 Gravity 类来填充,则会失去该预处理带来的好处,当容器为 RelativeLayout 时,框架可能必须执行多次遍历。
多次“布局和度量”遍历本身并不是性能负担,但如果发生在错误的地方,就可能会变成负担。您应该警惕容器存在以下情况:
- 它是视图层次结构中的根元素。
- 它下面有较深的视图层次结构。
- 屏幕中填充了它的许多实例,类似于 ListView 对象中的子对象。
诊断视图层次结构问题
布局性能是一个涉及许多方面的复杂问题。有几种工具可以为您提供关于性能瓶颈发生位置的明确提示。其他一些工具提供的信息不那么明确,但也能提供有用的提示。
Systrace
有一个工具可以提供关于性能的重要数据,那就是 Systrace,该工具内置在 Android SDK 中。利用 Systrace 工具,您可以在整个 Android 设备上收集和检查计时信息,从而了解布局性能问题何时导致性能问题。要详细了解 Systrace,请参阅系统跟踪概览。
GPU 渲染分析
另一款最有可能为您提供可靠的性能瓶颈信息的工具是设备端 GPU 渲染分析工具,该工具在搭载 Android 6.0(API 级别 23)及更高版本的设备上提供。通过此工具,您可以了解“布局和度量”阶段在每一帧渲染上花费的时间。此数据可以帮助您诊断运行时性能问题,以及确定需要解决哪些“布局和度量”问题(如果有)。
在其捕获的数据的图形表示中,GPU 渲染分析使用蓝颜色来代表布局时间。要详细了解如何使用此工具,请参阅 GPU 渲染分析演示。
Lint
Android Studio 的 Lint 工具可以帮助您了解视图层次结构中的低效问题。要使用此工具,请依次选择 Analyze > Inspect Code,如图 1 中所示。
图 1. 在 Android Studio 中找到 Inspect Code。
Android > Lint > Performance 下面显示了有关各种布局项目的信息。要查看更多详情,可以点击各个项目将其展开,然后在屏幕右侧的窗格中会显示详细信息。图 2 显示了此界面的一个示例。
图 2. 查看有关 Lint 工具发现的特定问题的信息。
点击其中一个项目,右侧窗格中就会显示与该项目相关的问题。
要详细了解该区域中显示的特定主题和问题,请参阅 Lint 文档。
Layout Inspector
Android Studio 的 Layout Inspector 工具提供关于应用视图层次结构的可视化表示。这是一种浏览应用层次结构的好方法,它提供关于特定视图父链的清晰的可视化表示,可帮助您检查应用构建的布局。
Layout Inspector 提供的视图还可以帮助您确定由“Double Taxation”引起的性能问题。它还可以让您通过一种简便的方法来识别嵌套布局的深层链或具有大量嵌套智能的布局区域,这是导致性能下降的另一个潜在因素。在这两种情况下,“布局和度量”阶段的开销可能会特别大,从而导致性能问题。
要了解详情,请参阅使用 Layout Inspector 调试布局。
解决视图层次结构问题
要解决由视图层次结构引起的性能问题,其背后的基本原理很简单,但实际操作起来却比较困难。防止因视图层次结构导致性能下降包括两个目标:一个是实现视图层次结构扁平化,一个是减少“Double Taxation”。本节将探讨实现这两个目标的一些策略。
移除多余的嵌套布局
开发者经常会过度使用嵌套布局。例如,可能会在 RelativeLayout 容器包含一个同样也是 RelativeLayout 容器的子级。这种嵌套实际是多余的,并且会给视图层次结构造成不必要的开销。
Lint 通常可以为您标记此类问题,从而减少调试时间。
采用 merge/include
造成多余嵌套布局的一个常见原因就是 <include> 标记。例如,您可以定义一个类似如下的可重复使用的布局:
<LinearLayout> <!-- some stuff here --> </LinearLayout>
然后,定义一个 include 标记将此项目添加到父容器中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/app_bg" android:gravity="center_horizontal">
<include layout="@layout/titlebar"/>
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello" android:padding="10dp" />
...
</LinearLayout>
该 include 会将第一个布局嵌套在第二个布局中,而此嵌套是不必要的。
merge 标记可以避免此问题。要了解此标记,请参阅通过 <include> 重复使用布局。
采用开销较低的布局
您可能无法调整现有的布局方案,使其不包含多余的布局。在某些情况下,唯一的解决方案可能是,通过切换到完全不同的布局类型来实现层次结构的扁平化。
例如,您可能会发现,TableLayout 作为具有许多位置依赖项的更复杂的布局,可以提供相同的功能。在 Android 的 N 版本中,ConstraintLayout 类提供了与 RelativeLayout 类似的功能,但开销要低得多。
相关推荐
- 30天学会Python编程:16. Python常用标准库使用教程
-
16.1collections模块16.1.1高级数据结构16.1.2示例...
- 强烈推荐!Python 这个宝藏库 re 正则匹配
-
Python的re模块(RegularExpression正则表达式)提供各种正则表达式的匹配操作。...
- Python爬虫中正则表达式的用法,只讲如何应用,不讲原理
-
Python爬虫:正则的用法(非原理)。大家好,这节课给大家讲正则的实际用法,不讲原理,通俗易懂的讲如何用正则抓取内容。·导入re库,这里是需要从html这段字符串中提取出中间的那几个文字。实例一个对...
- Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)
-
实现功能:Python数据分析实战-利用正则表达式提取文本中的URL网址和邮箱...
- python爬虫教程之爬取当当网 Top 500 本五星好评书籍
-
我们使用requests和re来写一个爬虫作为一个爱看书的你(说的跟真的似的)怎么能发现好书呢?所以我们爬取当当网的前500本好五星评书籍怎么样?ok接下来就是学习python的正确姿...
- 深入理解re模块:Python中的正则表达式神器解析
-
在Python中,"re"是一个强大的模块,用于处理正则表达式(regularexpressions)。正则表达式是一种强大的文本模式匹配工具,用于在字符串中查找、替换或提取特定模式...
- 如何使用正则表达式和 Python 匹配不以模式开头的字符串
-
需要在Python中使用正则表达式来匹配不以给定模式开头的字符串吗?如果是这样,你可以使用下面的语法来查找所有的字符串,除了那些不以https开始的字符串。r"^(?!https).*&...
- 先Mark后用!8分钟读懂 Python 性能优化
-
从本文总结了Python开发时,遇到的性能优化问题的定位和解决。概述:性能优化的原则——优化需要优化的部分。性能优化的一般步骤:首先,让你的程序跑起来结果一切正常。然后,运行这个结果正常的代码,看看它...
- Python“三步”即可爬取,毋庸置疑
-
声明:本实例仅供学习,切忌遵守robots协议,请不要使用多线程等方式频繁访问网站。#第一步导入模块importreimportrequests#第二步获取你想爬取的网页地址,发送请求,获取网页内...
- 简单学Python——re库(正则表达式)2(split、findall、和sub)
-
1、split():分割字符串,返回列表语法:re.split('分隔符','目标字符串')例如:importrere.split(',','...
- Lavazza拉瓦萨再度牵手上海大师赛
-
阅读此文前,麻烦您点击一下“关注”,方便您进行讨论和分享。Lavazza拉瓦萨再度牵手上海大师赛标题:2024上海大师赛:网球与咖啡的浪漫邂逅在2024年的上海劳力士大师赛上,拉瓦萨咖啡再次成为官...
- ArkUI-X构建Android平台AAR及使用
-
本教程主要讲述如何利用ArkUI-XSDK完成AndroidAAR开发,实现基于ArkTS的声明式开发范式在android平台显示。包括:1.跨平台Library工程开发介绍...
- Deepseek写歌详细教程(怎样用deepseek写歌功能)
-
以下为结合DeepSeek及相关工具实现AI写歌的详细教程,涵盖作词、作曲、演唱全流程:一、核心流程三步法1.AI生成歌词-打开DeepSeek(网页/APP/API),使用结构化提示词生成歌词:...
- “AI说唱解说影视”走红,“零基础入行”靠谱吗?本报记者实测
-
“手里翻找冻鱼,精心的布局;老漠却不言语,脸上带笑意……”《狂飙》剧情被写成歌词,再配上“科目三”背景音乐的演唱,这段1分钟30秒的视频受到了无数网友的点赞。最近一段时间随着AI技术的发展,说唱解说影...
- AI音乐制作神器揭秘!3款工具让你秒变高手
-
在音乐创作的领域里,每个人都有一颗想要成为大师的心。但是面对复杂的乐理知识和繁复的制作过程,许多人的热情被一点点消磨。...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 30天学会Python编程:16. Python常用标准库使用教程
- 强烈推荐!Python 这个宝藏库 re 正则匹配
- Python爬虫中正则表达式的用法,只讲如何应用,不讲原理
- Python数据分析实战-正则提取文本的URL网址和邮箱(源码和效果)
- python爬虫教程之爬取当当网 Top 500 本五星好评书籍
- 深入理解re模块:Python中的正则表达式神器解析
- 如何使用正则表达式和 Python 匹配不以模式开头的字符串
- 先Mark后用!8分钟读懂 Python 性能优化
- Python“三步”即可爬取,毋庸置疑
- 简单学Python——re库(正则表达式)2(split、findall、和sub)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)