RecyclerView详解——(四)缓存复用机制
稍微看了下源码和部分文章,在此做个小小的总结
RecyclerView,意思为可回收的view,那么相对于listview,他的缓存复用肯定是一大优化。
具体而言,当一个列表项被移出屏幕后,RecyclerView并不会销毁其视图,而是会缓存起来,以提供给新进入屏幕的列表项重用,这种重用不但可以避免重复创建不必要的视图,还可以避免重复执行昂贵的findViewById从而达到的改善性能、提升应用响应能力、降低功耗的效果。
一、核心类
Recycler,这个类是 RecycelerView 缓存复用机制的核心。
在我们常规使用RecyclerView时,与RecyclerView构建动态列表相关联的几个重要类中,Adapter与ViewHolder负责配合使用,共同定义RecyclerView列表项数据的展示方式,其中:
-
ViewHolder是一个包含列表项视图(itemView)的封装容器,同时也是RecyclerView缓存复用的主要对象。 -
Adapter则提供了数据和视图间的“绑定”关系,其包含以下几个关键方法:- onCreateViewHolder:负责创建并初始化ViewHolder及其关联的视图,但不会填充视图内容。
- onBindViewHolder:负责提取适当的数据,填充ViewHolder的视图内容。
而RecyclerView的缓存机制则可以减少onCreateViewHolder和onBindViewHolder的调用,从而达到减少开销,提高性能的效果。
最优解就是两个方法都不调用,直接复用,次解是只需要调用onBindViewHolder进行数据的绑定,而不需要去重新绑定View,最差解肯定是两个都需要去调用了。
public final class Recycler {final ArrayList<RecyclerView.ViewHolder> mAttachedScrap = new ArrayList<>();ArrayList<RecyclerView.ViewHolder> mChangedScrap = null;final ArrayList<RecyclerView.ViewHolder> mCachedViews = new ArrayList<RecyclerView.ViewHolder>();RecyclerView.RecycledViewPool mRecyclerPool;private RecyclerView.ViewCacheExtension mViewCacheExtension;}
从上述代码可以看出,缓存复用的对象是 ViewHolder。上面五个成员变量就是我们常说的 RecyclerView 的四级缓存,分别是:
-
mChangedScrap/mAttachedScrap主要用于临时存放仍在当前屏幕可见、但被标记为「移除」或「重用」的列表项,其均以ArrayList的形式持有着每个列表项的ViewHolder对象,大小无明确限制,但一般来讲,其最大数就是屏幕内总的可见列表项数。
-
其中,mChangedScrap主要是为列表项数据发生变化时的动画效果服务的。mChangedScrap缓存中的ViewHolder是需要调用onBindViewHolder方法重新绑定数据的。
-
mAttachedScrap应对的则是剩下的绝大部分场景,比如:像notifyItemMoved、notifyItemRemoved这种列表项发生移动,但列表项数据本身没有发生变化的场景。如果和RecyclerView上的position或者itemId匹配上了,那么认为是干净的ViewHolder,是可以直接拿出来使用的,无需调用onBindViewHolder方法。
-
mCachedViews,用来缓存移出屏幕之外的 ViewHolder(但有可能很快重新进入屏幕的列表项)。只要position或者itemId对应上了,就无需重新绑定数据,默认大小为2,可以通过 public void setItemViewCacheSize(int size) {
mRecycler.setViewCacheSize(size);
} 修改缓存大小mViewCacheExtension,这一层的创建和缓存完全由开发者自己控制,初始值为null。这一层很少会用到。mRecyclerPool,ViewHolder 缓存池。mRecyclerPool主要用于按不同的itemType分别存放超出mCachedViews限制的、被移出屏幕的列表项,其会先以SparseArray区分不同的itemType,然后每种itemType对应的值又以ArrayList的形式持有着每个列表项的ViewHolder对象,每种itemType的ArrayList大小限制默认为5。可通过setMaxRecycledViews(itemType,size)修改大小.
二、Recycler的源码调用
public final class Recycler {.../*** 尝试通过从Recycler scrap缓存、RecycledViewPool查找或直接创建的形式来获取指定位置的ViewHolder。*/@NullableViewHolder tryGetViewHolderForPositionByDeadline(int position,boolean dryRun, long deadlineNs) {if (mState.isPreLayout()) {// 0 尝试从mChangedScrap中获取ViewHolder对象holder = getChangedScrapViewForPosition(position);...}if (holder == null) {// 1.1 尝试根据position从mAttachedScrap或mCachedViews中获取ViewHolder对象holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);...}if (holder == null) {...final int type = mAdapter.getItemViewType(offsetPosition);if (mAdapter.hasStableIds()) {// 1.2 尝试根据id从mAttachedScrap或mCachedViews中获取ViewHolder对象holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),type, dryRun);...}if (holder == null && mViewCacheExtension != null) {// 2 尝试从mViewCacheExtension中获取ViewHolder对象final View view = mViewCacheExtension.getViewForPositionAndType(this, position, type);if (view != null) {holder = getChildViewHolder(view);...}}if (holder == null) { // fallback to pool// 3 尝试从mRecycledViewPool中获取ViewHolder对象holder = getRecycledViewPool().getRecycledView(type);...}if (holder == null) {// 4.1 回调createViewHolder方法创建ViewHolder对象及其关联的视图holder = mAdapter.createViewHolder(RecyclerView.this, type);...}}if (mState.isPreLayout() && holder.isBound()) {...} else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {...// 4.1 回调bindViewHolder方法提取数据填充ViewHolder的视图内容bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs);}...return holder;}...}
从上述代码中,可以看到他们的调用顺序为依次从mChangedScrap/mAttachedScrap、mCachedViews、mViewCacheExtension、mRecyclerPool中尝试获取指定位置或ID的ViewHolder对象以供重用,如果全都获取不到则直接重新创建。
参考文章:
https://juejin.cn/post/7344941254236749851?searchId=202411182234361EC6BF29AC9F2C8D6DB5
https://juejin.cn/post/7344941254236749851?searchId=202411182234361EC6BF29AC9F2C8D6DB5关于RecyclerView和ListView的缓存对比
https://juejin.cn/post/6844903448974983181?searchId=20241118230728641CF838198392957185
https://juejin.cn/post/6844903448974983181?searchId=20241118230728641CF838198392957185
相关文章:
RecyclerView详解——(四)缓存复用机制
稍微看了下源码和部分文章,在此做个小小的总结 RecyclerView,意思为可回收的view,那么相对于listview,他的缓存复用肯定是一大优化。 具体而言,当一个列表项被移出屏幕后,RecyclerView并不会销毁其视图&a…...
进程 系统调用 中断
进程P通过执行系统调用从键盘接收一个字符的输入,已知此过程中与进程P相关的操作包括: ①将进程P插入就绪队列; ②将进程P插入阻塞队列; ③将字符从键盘控制器读入系统缓冲区; ④启动键盘中断处理程序; …...
演讲回顾丨杭州悦数 CTO 叶小萌:图数据库发展新航向——拥抱 GQL,融合 HTAP,携手 AI
本文为杭州悦数 CTO 叶小萌在“标准智能:新质生产力的原动力”悦数图数据库新产品发布会上的演讲回顾,主题为:《新标准、新期待:展望图数据库发展的关键方向》 各位嘉宾、悦数图数据库的用户以及线上的观众朋友们大家好࿰…...
Java安全—JNDI注入RMI服务LDAP服务JDK绕过
前言 上次讲到JNDI注入这个玩意,但是没有细讲,现在就给它详细地讲个明白。 JNDI注入 那什么是JNDI注入呢,JNDI全称为 Java Naming and Directory Interface(Java命名和目录接口),是一组应用程序接口&…...
C++:设计模式-单例模式
单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并且提供全局访问点。实现单例模式的关键是防止类被多次实例化,且能够保证实例的唯一性。常见的实现手法包括懒汉式、饿汉式、线程安全的懒汉式等。…...
Softing工业将OPC UA信息建模集成到边缘应用和安全集成服务器中
Softing工业宣布将OPC UA(统一架构)信息建模集成到其边缘产品系列及安全集成服务器(SIS)中,这一技术进步使得在工业物联网(IIoT)应用中的数据集成、交换与控制更加无缝、有效。 (OPC…...
WPF中如何让Textbox显示为一条直线
由于Textbox直接使用是一条直线 设置如下代码 可以让Textbox变为直线输入 <Style TargetType"TextBox"x:Key"UsernameTextBoxStyle"><Setter Property"Template"><Setter.Value><ControlTemplate TargetType"{x:Typ…...
VSCode汉化教程【简洁易懂】
我们安装完成后默认是英文界面。 找到插件选项卡,搜索“Chinese”,找到简体(更具你的需要)(Microsoft提供)Install。 安装完成后选择Change Language and Restart。...
跨平台多开账号防关联:轻松管理多个账号!
对于跨境电商、独立站以及社媒营销领域,如何高效管理多个账号、确保账号安全是企业面临的重大挑战。那么如何仅用一台电脑就能实现跨平台多开账号呢? 一、为什么需要跨平台多开账号并防关联? 1. 品牌推广:不同平台拥有不同的用户…...
DICOM图像处理:深入解析DICOM彩色图像中的Planar配置及其对像素数据解析处理的实现
引言 在DICOM(Digital Imaging and Communications in Medicine)标准中,彩色图像的存储与显示涉及多个关键属性,其中**Planar Configuration(平面配置)**属性(标签 (0028,0006))尤为重要。当遇到彩色DICOM图像在浏览时被错误地分割为9张小图,而实际应显示为一…...
jupyter notebook的 markdown相关技巧
目录 1 先选择为markdown类型 2 开关技巧 2.1 运行markdown 2.2 退出markdown显示效果 2.3 注意点:一定要 先选择为markdown类型 3 一些设置技巧 3.1 数学公式 3.2 制表 3.3 目录和列表 3.4 设置各种字体效果:加粗,斜体&#x…...
Linux连接网络的三种方式
Linux 连接网络的三种常见方式如下: 桥接模式 原理:虚拟网络接口与物理网络接口或另一个虚拟接口 “桥接”,形成逻辑上的网络交换机,使所有通过该桥接设备的数据包能被转发到桥接组中的所有接口,如同在一个局域网内…...
##继承##
继承的概念 #继承是新模板基于老模板的基础上修改而成,制作新模板时不需要重新开始制作,可以在老模板的基础上进行修改.(如手机版本的换代,软件的版本更新等) #程序也可以继承 继承的格式: class 继承模块(被继承模块ÿ…...
2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略 完整参考论文(1)
摘要 近年来,中国宠物食品行业迅速增长,但面临复杂的国际形势和多变的市场环境,因此科学地分析和预测该行业的发展趋势至关重要。本研究通过构建多个机器学习与统计回归模型,量化分析中国宠物食品行业的关键驱动因素,预测未来宠物食品总产值和出口值。 在数据处理部分,…...
uni-app 修改复选框checkbox选中后背景和字体颜色
编写css(注意:这个样式必须写在App.vue里) /* 复选框 */ /* 复选框-圆角 */ checkbox.checkbox-round .wx-checkbox-input, checkbox.checkbox-round .uni-checkbox-input {border-radius: 100rpx; } /* 复选框-背景颜色 */ checkbox.checkb…...
使用Notepad++工具去除重复行
使用Notepad工具去除重复行 参考链接:https://blog.csdn.net/londa/article/details/108981396 一 、使用正则表达式 1、对文本进行排序,让重复行排在一起 2、使用正则表达式替换(注意)^(.*?)$\s?^(?.*^\1$) 在替换时选择正…...
基于Springboot+Vue的救灾物资调动系统 (含源码数据库)
1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…...
Unity 使用 Excel 进行配置管理(读Excel配置表、Excel转保存Txt 文本、读取保存的 Txt 文本配置内容)
Unity 使用 Excel 进行配置管理(读Excel配置表、Excel转保存Txt 文本、读取保存的 Txt 文本配置内容) 目录 Unity 使用 Excel 进行配置管理(读Excel配置表、Excel转保存Txt 文本、读取保存的 Txt 文本配置内容) 一、简单介绍 二、实现原理 三、注意事项 四、案例简单步…...
MySQL中索引全详解
第一部分:什么是索引 索引在数据库中就像书的目录,能够快速定位数据位置,从而提升查询效率。没有索引时,数据库查询需要从头到尾扫描整个表(称为全表扫描),这在数据量大时非常耗时。有了索引后&…...
vllm serve的参数大全及其解释
以下是 vllm serve 的常见参数说明以及它们的作用: 1. 基本参数 model_tag 说明:用于指定要加载的模型,可以是 Hugging Face 模型仓库中的模型名称,也可以是本地路径。示例:vllm serve "gpt-neo-2.7B"--co…...
野兽派不是乱来:拆解Midjourney V6中色彩暴力、笔触失序与构图反叛的5层参数逻辑
更多请点击: https://kaifayun.com 第一章:野兽派不是乱来:Midjourney V6的美学暴动宣言 Midjourney V6 不是一次平滑迭代,而是一场蓄谋已久的视觉政变——它将“语义精确性”与“风格不可预测性”焊死在同一张提示词底片上。当 …...
py每日spider案例之netease搜索接口获取
import requestsheaders = {"accept": "application/json, text/plain, */*","accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7","cache-control": "no-cache",...
毕业设计精选【芳心科技】无人机定点投放控制
实物效果图:实现功能:本次设计的目的是实现无人机在空中投放物品的落点计算,系统的核心是单片机,它控制本系统的各种功能,所以它的选择是非常重要的,在本设计中选用的是GD32F103C8T6单片机,这款…...
Zed与VSCode争议背后真相:性能瓶颈到底是谁的锅
别被骗了!Zed比VS Code快?真正的原因让你哭笑不得!本文深入分析开发者社区对Zed编辑器与VS Code的争议,澄清性能瓶颈的真相在于语言服务器协议(LSP)而非编辑器本身,揭示Zed真正的优势在于原生Vim模式和架构简洁性&…...
这份榜单够用!盘点2026年断层领先的的AI论文写作软件
一天写完毕业论文在2026年已不再是天方夜谭。以下是2026年最炸裂、实测能大幅提速的AI论文写作软件,覆盖选题构思、文献综述、数据整理、格式排版等核心场景,帮你高效搞定论文。 一、全流程王者:一站式搞定论文全链路(一天定稿首选…...
中兴B863AV3.2-M刷机避坑指南:S905L3A芯片识别、固件选择与Amlogic USB Burning Tool 2.2.0配置详解
中兴B863AV3.2-M刷机全流程精解:从芯片识别到固件烧录的进阶实践 在智能电视盒的玩家圈子里,中兴B863AV3.2-M因其出色的硬件配置和可玩性备受关注。这款搭载Amlogic S905L3A芯片的设备,通过刷机可以解锁更多功能,但过程中暗藏的&q…...
【Midjourney纹理生成高阶秘籍】:20年AI视觉工程师亲授5大不可外传的材质控制法则
更多请点击: https://kaifayun.com 第一章:纹理生成的本质:从像素噪声到物理材质的范式跃迁 纹理生成早已超越了早期“随机像素着色”的朴素阶段,演进为融合程序化建模、物理渲染方程(PBR)与微表面理论的系…...
【紧急预警】ElevenLabs 2024 Q3瑞典文语音许可证变更:3类商业场景已触发合规风险,附欧盟GDPR语音数据处理自查清单
更多请点击: https://codechina.net 第一章:ElevenLabs瑞典文语音许可证变更的合规背景与影响速览 2024年第三季度,ElevenLabs正式更新其语音合成服务的区域许可政策,将瑞典语(sv-SE)语音模型纳入欧盟《人…...
从零搭建 Geo 开源项目源码开发环境——以 GeoServer 为例
在地理信息(GIS)与空间数据服务开发中,Geo 系开源项目(如 GeoServer、GeoPandas、GeoDjango 等)非常常见。很多团队后期都会走到“读源码 / 改源码 / 二次开发”这一步,而第一步往往是:把源码跑…...
为什么顶级AI艺术家总在第3轮生成才出片?——揭秘构图迭代中的“临界收敛点”与3次生成内锁定最佳构图的硬核策略
更多请点击: https://kaifayun.com 第一章:为什么顶级AI艺术家总在第3轮生成才出片? AI图像生成并非“一击必中”的魔法,而是一场精密的概率博弈。Stable Diffusion、DALLE 3 和 MidJourney v6 等主流模型在采样过程中采用多步去…...
