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…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
