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

安卓 MeasureCache优化了什么?

安卓绘制原理概览_油炸板蓝根的博客-CSDN博客

        搜了一下,全网居然没有人提过 measureCache。

        在前文中提到过,measure的时候,如果命中了 measureCache,会跳过 onMeasure,同时会设置 PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT标志位,其作用顾名思义,需要在 layout 前进行 measure。

public class View {public final void measure(int widthMeasureSpec, int heightMeasureSpec) {if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);......int cacheIndex = forceLayout? -1: mMeasureCache.indexOfKey(key);if (cacheIndex < 0 || sIgnoreMeasureCache) {// measure ourselves, this should set the measured dimension flag backonMeasure(widthMeasureSpec, heightMeasureSpec);mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;} else {long value = mMeasureCache.valueAt(cacheIndex);// Casting a long to int drops the high 32 bits, no mask neededsetMeasuredDimensionRaw((int) (value >> 32), (int) value);mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;}}public void layout(int l, int t, int r, int b) {if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;}...}
}

        这里有点令人疑惑,为什么在 measure 中跳过了 onMeasure,但又在 layout 中找补了回来。不执行可以优化性能耗时,但这里又重新执行了一次,优化在哪里?既然有这段代码,那么就一定是优化的,我们先有一下两种猜测:

  1. 前一次和后一次执行的逻辑不同,前一次的性能耗时长,后一次的性能耗时短,所以有优化。
  2. 优化了执行次数,前者执行次数比后者多。

        让我们先看一下引入 measureCache 的 commit message,看看作者怎么说的。

Skip unnecessary measurements when possible.

This change introduces a new measure cache to View, to remember the measured dimensions for previous pairs of measure specs. The measure cache is cleared whenever a View requests layout.

Unfortunately some Views rely on measure being always called when layout is invoked. To work around this problem, we need to remember when we hit the measure cache to force a call to measure just prior to calling onLayout(). This does not completely removes all measure calls but enough to optimize a number of layouts.

跳过不必要的 measure。这次改动针对 view 引入了新的measure 缓存,其可以记录已经测量过的measure specs。每次 view requestLayout的时候,都会清除 measure cache。

不幸的是,一些 view 在layout 调用的时候,总是需要 measure 调用。为了解决这个问题,我们需要在命中 measure 缓存的时候,强制在 OnLayout中调用  onMeasure。这种做法没有完全移除 measure 的调用,但是也已经足够优化一部分了。

跳过 onMeasure虽然可以提高效率,但是有一些自定义 view 是依赖其 onMeasure 流程保证其正常工作的。换句话说,一些自定义 View 的 onMeasure 方法不仅仅完成了可以被跳过的 measurement,还执行了某些不能被跳过的流程。 例如 ViewPager

public class ViewPager {protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// measure self and decor...// update childrenpopulate();// measure children...}
}

        ViewPager 依赖onMeasure 更新 page,如果 onMeasure 被跳过,就有可能出现 page 错位的情况。除了 ViewPager,RecyclerView、CoordinateLayout 等复杂度较高的组件也都在 onMeasure 中做了许多复杂的工作。既然 onMeasure 一定要执行,那么 measureCache 的优化工作又体现在哪里呢?毕竟 commit message 最后写了“but enough to optimize a number of layouts.” 

        measureCache 可以将一次 Traversal 中多次冗余 onMeasure 减少为一次,对于很多 ViewGroup,在 onMeasure 阶段往往会不止一次的调用 child 的 measure,例如RelativeLayout 、使用了 weight 的 LinearLayout、ConstraintLayout 等等,measureCache 的存在使得 child 本应该在 parent view onMeasure 阶段执行的多次 measure 被延后到 layout 阶段,且仅执行一次。

public class RelativeLayout extends ViewGroup {protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {measureChildHorizontal(child, params, myWidth, myHeight);measureChild(child, params, myWidth, myHeight);setMeasuredDimension(width, height);}
}

        假设 A、B、C 都是一个需要测量孩子两次的 ViewGroup,那么如果没有 MeasureCache,当执行 A 的 Measure 时候,将会调用 BBCC,共四次 measure,同样的调用DDEEDDEEFFGGFFGG,共 16 次 measure。但是如果有 measureCache,在 measure 阶段,将会调用 A 的 measure(如果 A 是顶 viewGroup),然后直接设置 B、C 的大小。只调用了 1 次。然后在 layout 阶段,调用一次 B 的 onMeasure、一次 C 的 onMeasure,DEFG 的 onMeasure 各一次。所以只调用了六次。已经足够优化了。 

相关文章:

安卓 MeasureCache优化了什么?

安卓绘制原理概览_油炸板蓝根的博客-CSDN博客 搜了一下&#xff0c;全网居然没有人提过 measureCache。 在前文中提到过&#xff0c;measure的时候&#xff0c;如果命中了 measureCache&#xff0c;会跳过 onMeasure&#xff0c;同时会设置 PFLAG3_MEASURE_NEEDED_BEFORE_LAYOU…...

docker save docker export 区别

docker save用于导出镜像到文件&#xff0c;包含镜像元数据和历史信息&#xff1b;docker export用于将当前容器状态导出至文件&#xff0c;类似快照&#xff0c;所以不包含元数据及历史信息&#xff0c;体积更小&#xff0c;此外从容器快照导入时也可以重新指定标签和元数据信…...

音频基础知识

文章目录 前言一、音频基本概念1、音频的基本概念①、声音的三要素②、音量与音调③、几个基本概念④、奈奎斯特采样定律 2、数字音频①、采样②、量化③、编码④、其他相关概念<1>、采样位数<2>、通道数<3>、音频帧<4>、比特率&#xff08;码率&#…...

TensorFlow(R与Python系列第四篇)

目录 一、TensorFlow介绍 二、张量 三、有用的TensorFlow运算符 四、reduce系列函数实现约减 1-第一种理解方式&#xff1a;引入轴概念后直观可理 2-第二种理解方式&#xff1a;按张量括号层次的方式 参考&#xff1a; 一、TensorFlow介绍 TensorFlow是一个强大的用于数…...

华为数通方向HCIP-DataCom H12-821题库(单选题:261-280)

第261题 以下关于IPv6过渡技术的描述,正确的是哪些项? A、转换技术的原理是将IPv6的头部改写成IPv4的头部,或者将IPv4的头部改写成IPv6的头部 B、使用隧道技术,能够将IPv4封装在IPv6隧道中实现互通,但是隧道的端点需要支持双栈技术 C、转换技术适用于纯IPv4网络与纯IPv…...

论文《基于概率标签估计的半监督日志缺陷检测》翻译

论文《Semi-supervised Log-based Anomaly Detection via Probabilistic Label Estimation》翻译 Semi-supervised Log-based Anomaly Detection via Probabilistic Label Estimation翻译...

ajax day2

1、 2、控制弹框显示和隐藏&#xff1a; 3、右键tr&#xff0c;编辑为html&#xff0c;可直接复制tr部分的代码 4、删除时&#xff0c;点击删除按钮&#xff0c;可以获取图书id&#xff1a; 5、编辑图书 快速赋值表单元素内容&#xff0c;用于回显&#xff1a; 6、hidden …...

互联网摸鱼日报(2023-09-04)

互联网摸鱼日报(2023-09-04) 36氪新闻 腾讯游戏的棋中妙手 逐一解读北交所8大改革组合拳 本周双碳大事&#xff1a;全国碳市场清缴履约工作全面展开&#xff1b;宁德时代在成都成立新能源研究院&#xff1b;我国首个万吨级光伏发电直接制绿氢项目投产 你在上海 city walk&a…...

UG\NX CAM二次开发 遍历组中的工序 UF_NCGROUP_ask_member_list

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 遍历组中的工序 UF_NCGROUP_ask_member_list 效果: 代码: void GetAllOperTag(tag_t groupTag, vector<tag_t> &vOperTags) {int count=0;tag_t * list;UF_NCGROUP_ask_member_li…...

适配器、装饰器模式

一、装饰器模式 向一个现有的对象增加其功能而不改变其结构&#xff0c;属于类的包装...

Netty服务端启动的整体流程-基于源码4.1.96Final分析

Netty采用的是主从Reactor多线程的模型&#xff0c;参考Scalable IO in Java&#xff0c;但netty的subReactor为一个组 一、从FileServer服务器示例入手 public final class FileServer {static final boolean SSL System.getProperty("ssl") ! null;// Use the …...

预训练Bert添加new token的问题

问题 最近遇到使用transformers的AutoTokenizer的时候&#xff0c;修改vocab.txt中的[unused1]依然无法识别相应的new token。 实例&#xff1a; 我将[unused1]修改为了[TRI]&#xff0c;句子中的[TRI]并没有被整体识别&#xff0c;而是识别为了[,T,RI,]。这明显是有问题的。…...

非常典型和高效的枚举类写法

目录 1、讲讲好处 2、例子 &#xff08;1&#xff09;枚举类&#xff1a; &#xff08;2&#xff09;DTO类&#xff1a; 3、根据上面例子进行具体讲解 1、讲讲好处 在使用这种标准枚举模式编写业务逻辑时,可以直接通过枚举成员来表示状态,不需要担心底层的 value 或描述信…...

kafka-- kafka集群环境搭建

kafka集群环境搭建 # 准备zookeeper环境 (zookeeper-3.4.6) # 下载kafka安装包 https://archive.apache.org/dist/kafka/2.1.0/kafka_2.12-2.1.0.tgz # 上传 : 172.16.144.133 cd /usr/local/softwaretar -zxvf /usr/local/software/kafka_2.12-2.1.0.tgz -C /usr/local…...

3.flask-sqlalchemy ORM库

介绍 Flask-SQLAlchemy是一个用于Flask的扩展&#xff0c;它提供了一个便捷的方式来处理数据库操作。Flask-SQLAlchemy基于SQLAlchemy&#xff0c;一个功能强大的Python SQL工具包和对象关系映射&#xff08;ORM&#xff09;系统 官网文档:http://www.pythondoc.com/flask-sql…...

mac 安装 homebrew

摘要&#xff1a; 本文主要是下载安装包安装homebrew&#xff0c;然后配置环境变量Path。检验是否安装成功。 homebrew地址&#xff1a;macOS&#xff08;或 Linux&#xff09;缺失的软件包的管理器 — Homebrew 在终端命令下载安装&#xff1a; /bin/bash -c "$(curl…...

R语言应用interactionR包进行亚组相加交互作用分析

在统计分析中交互作用是指某因素的作用随其他因素水平变化而变化&#xff0c;两因素共同作用不等于两因素单独作用之和(相加交互作用)或之积(相乘交互作用)。相互作用的评估是尺度相关的&#xff1a;乘法或加法。乘法尺度上的相互作用意味着两次暴露的综合效应大于&#xff08;…...

mysql 数据库面试题整理

Mysql 中 MyISAM 和 InnoDB 的区别 1、InnoDB 支持事务MyISAM 不支持 2、InnoDB 支持外键MyISAM 不支持 3、InnoDB 是聚集索引&#xff0c;MyISAM 是非聚集索引 4、InnoDB 不保存表的具体行数 5、InnoDB 最小的锁粒度是行锁&#xff0c;MyISAM是表锁 mysql中有就更新&#xf…...

LeetCode-435-无重叠区间

题目链接&#xff1a; 力扣435 -无重叠区间 解题思路&#xff1a;和之前的合并区间、汇总区间都比较相似&#xff0c; 先对二维数组排序&#xff0c;按照左边界升序&#xff1b;当 当前区间的左区间 < 前一个区间的右区间&#xff0c;说明有重叠&#xff0c;res1,还要更新当…...

记录深度学习常用指令(一)

一、创建Conda虚拟Python环境 conda create -n [仓库名字] python[版本]二、激活环境 conda activate [仓库名字]三、安装PyTorch PyTorch官方 GPU&#xff1a; conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorchCPU&#xff1…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...