一、四级缓存体系

1. Scrap 缓存(临时缓存)

  • 位置mAttachedScrap 和 mChangedScrap

  • 作用

    • 存储当前屏幕可见但被标记为移除的 ViewHolder

    • 用于局部刷新(如 notifyItemChanged()

  • 特点

    • 生命周期短(仅在一次布局过程中有效)

    • 不需要重新绑定数据(onBindViewHolder 不被调用)

    • 按位置索引存储

2. CacheViews(一级缓存)

  • 位置mCachedViews(默认大小 = 2)

  • 作用

    • 存储刚刚滚出屏幕的 ViewHolder

    • 支持快速反向滚动恢复

  • 特点

    • 按位置索引存储

    • 不需要重新绑定数据

    • 当新项加入时,最老的项会被移到 RecycledViewPool

3. ViewCacheExtension(二级缓存 - 自定义)

  • 开发者扩展层

    public abstract static class ViewCacheExtension {public abstract View getViewForPositionAndType(Recycler recycler, int position, int type);
    }
  • 作用:允许开发者实现自定义缓存逻辑

  • 使用场景

    • 缓存特定位置的视图(如固定头部)

    • 预加载复杂视图

  • 注意:官方建议谨慎使用,大多数场景无需实现

4. RecycledViewPool(三级缓存)

  • 位置mRecyclerPool

  • 作用

    • 存储不同类型(viewType)的 ViewHolder 池

    • 支持跨位置复用

  • 特点

    • 按 viewType 分类存储(SparseArray<ScrapData>

    • 需要重新绑定数据(会调用 onBindViewHolder

    • 默认每个类型缓存 5 个 ViewHolder

    • 可全局共享(多个 RecyclerView 共用)

二、缓存获取优先级

当需要新视图时,RecyclerView 按以下顺序查询:

三、缓存生命周期详解

四、性能优化策略

1. 调整缓存大小

// 扩大一级缓存(默认2)
recyclerView.itemViewCacheSize = 10// 扩大回收池缓存(默认每个类型5个)
recyclerView.recycledViewPool.setMaxRecycledViews(viewType, 15)

2. 共享回收池(多列表优化)

// 创建共享池
val sharedPool = RecyclerView.RecycledViewPool()// 多个RecyclerView共享
recyclerView1.recycledViewPool = sharedPool
recyclerView2.recycledViewPool = sharedPool

3. 预加载机制

// 启用Item预取(Android 5.0+)
recyclerView.layoutManager?.isItemPrefetchEnabled = true// 设置预取数量
(recyclerView.layoutManager as LinearLayoutManager).initialPrefetchItemCount = 10

4. 优化ViewHolder创建

// 使用ViewStub延迟加载复杂布局
public class ComplexViewHolder extends RecyclerView.ViewHolder {private ViewStub stub;private View inflatedView;public ComplexViewHolder(View itemView) {super(itemView);stub = itemView.findViewById(R.id.complex_view_stub);}public void bind(boolean showComplex) {if (showComplex && inflatedView == null) {inflatedView = stub.inflate();}}
}

5. 监控缓存命中率

// 添加调试监听器
recyclerView.addOnChildAttachStateChangeListener(object : RecyclerView.OnChildAttachStateChangeListener {override fun onChildViewAttachedToWindow(view: View) {val holder = recyclerView.getChildViewHolder(view)when {holder.isRecyclable -> println("从缓存池复用")holder.isAttachedToTransitionOverlay -> println("从CacheViews复用")holder.isTmpDetached -> println("从Scrap复用")else -> println("全新创建")}}
})

五、缓存机制与DiffUtil的协同

六、最佳实践总结

  1. 合理设置缓存大小

    • 小列表(<50项):默认值足够

    • 中大型列表:增大 itemViewCacheSize(5-15)

    • 超长列表:增大 RecycledViewPool(10-20)

  2. 优化ViewHolder

    • 避免复杂布局嵌套

    • 使用 ConstraintLayout 减少层级

    • 耗时操作放在 onViewRecycled 释放

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94974.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94974.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/94974.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型SSE流式输出技术

文章目录背景&#xff1a;为什么需要流式输出SSE 流式输出很多厂商还是小 chunk背景&#xff1a;为什么需要流式输出 大模型的响应通常很长&#xff0c;比如几百甚至几千个 token&#xff0c;如果等模型一次性生成完才返回&#xff1a; 延迟高&#xff1a;用户要等很久才能看…

[Flutter] v3.24 AAPT:错误:未找到资源 android:attr/lStar。

推荐超级课程&#xff1a; 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战 前提 将 Flutter 升级到 3.24.4 后&#xff0c;构建在我的本地电脑上通过&#xff0c;但Github actions 构建时失败。 Flutt…

go语言标准库学习, fmt标准输出,Time 时间,Flag,Log日志,Strconv

向外输出 fmt包实现了类似C语言printf和scanf的格式化I/O。主要分为向外输出内容和获取输入内容两大部分。 内置输出 不需要引入标准库&#xff0c;方便 package mainfunc main() {print("我是控制台打印&#xff0c;我不换行 可以自己控制换行 \n我是另一行")prin…

ElementUI之表格

文章目录使用ElementUI使用在线引入的方式表格1. 带状态表格row-class-name"Function({row, rowIndex})/String"2. 固定表头(height"string/number"属性)2.1 属性的取值2.2 动态响应式高度使用演示2.3 ​​自定义滚动条样式​​2.4 表头高度定制获取一行信…

K8S 的 Master组件

K8S 的 Master 组件有哪些&#xff1f;每个组件的作用&#xff1f; K8s 大脑的 4 大核心模块&#xff0c;掌控全局&#xff01; Kubernetes 集群的 Master&#xff08;主节点&#xff09; 就像一座 指挥中心&#xff0c;负责整个集群的调度、管理和控制。它由 4 大核心组件组成…

如何 让ubuntu 在root 下安装的docker 在 普通用户下也能用

在 Ubuntu 系统中&#xff0c;如果 Docker 是以 root 用户安装的&#xff0c;普通用户默认无法直接使用 Docker 命令&#xff08;会报权限错误&#xff09;。要让普通用户也能使用 Docker&#xff0c;可以按照以下步骤操作&#xff1a;方法 1&#xff1a;将用户加入 docker 用户…

模板方法模式:优雅封装算法骨架

目录 一、模板方法模式 1、结构 2、特性 3、优缺点 3.1、优点 3.2、缺点 4、使用场景 5、实现示例 5.1、抽象类 5.2、实现类 5.3、测试类 一、模板方法模式 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它在一个方…

韦东山STM32_HAl库入门教程(SPI)学习笔记[09]内容

&#xff08;1&#xff09;SPI程序层次一、核心逻辑&#xff1a;“SPI Flash 操作” 是怎么跑起来的&#xff1f;要读写 SPI Flash&#xff0c;需同时理解 硬件连接&#xff08;怎么接线&#xff09; 和 软件分层&#xff08;谁负责发指令、谁负责控制逻辑&#xff09;&#xf…

线上Linux服务器的优化设置、系统安全与网络安全策略

一、Linux服务器的优化设置 线上Linux的优化配置序号基础优化配置内容说明1最小化安装系统【仅安装需要的&#xff0c;按需安装、不用不装】&#xff0c;必须安装的有基本开发环境、基本网络包、基本应用包。2ssh登录策略优化 Linux服务器上的ssh服务端配置文件是【/et…

基于人眼视觉特性的相关图像增强基础知识介绍

目录 1. 传统的灰度级动态范围优化配置方法 2.基于视觉特性的灰度级动态范围调整优化 1. 传统的灰度级动态范围优化配置方法 传统的灰度级动态范围调整方法主要包括线性动态范围调整及非线性动态 范围调整。线性动态范围调整是最简单的灰度级动态范围调整方法&#xff0c;观察…

Selenium使用超全指南

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快概述selenium是网页应用中最流行的自动化测试工具&#xff0c;可以用来做自动化测试或者浏览器爬虫等。官网地址为&#xff1a;相对于另外一款web自动化测试工具QT…

Go通道操作全解析:从基础到高并发模式

一、channel类型 Go 语言中的通道(channel)是一种特殊的类型。它类似于传送带或队列,遵循先进先出(FIFO)原则,确保数据收发顺序的一致性。每个通道都是特定类型的导管,因此在声明时必须指定其元素类型。 channel是一种类型, 一种引用类型。 声明通道类型的格式如下:…

Linux网络--1、网络基础

目录 一、网络发展 二、理解分层 2.1OSI七层模型 2.2TCP/IP分层模型 2.3分层的好处 三、认识协议 3.1初步认识 3.2了解指定组织 3.3具体协议理解 3.3.1是什么 3.3.2为什么 3.3.3与OS的关系 3.4总结 四、网络传输流程 4.1局域网网络传输 4.1.1通信过程 4.1.2概念解析 4.2跨网…

前端视角下关于 WebSocket 的简单理解

参考 RFC 6455: The WebSocket Protocol WebSocket 协议基础 协议本质&#xff1a;在单个 TCP 连接上提供全双工通信通道的协议核心优势&#xff1a; 双向实时通信&#xff08;服务器主动推送&#xff09;低延迟&#xff08;相比 HTTP 轮询&#xff09;高效数据传输&#xff0…

自动化一键部署 LNMP 环境

第一步&#xff1a;准备环境 & 准备脚本文件1. 你在 CentOS 7 的服务器/虚拟机里打开终端&#xff0c;确认你有 root 权限或者能用 sudo。输入下面命令确认你的系统版本&#xff1a;cat /etc/centos-release你应该看到类似&#xff1a;CentOS Linux release 7.9.2009 (Core…

react之React.cloneElement()

react提供的这个方法克隆组件的方法&#xff0c;可能我们在平常的开发中用的很少&#xff0c;主要可能是我们并不知道或者并不了解这个方法。因为我在之前react的children文章中用到过&#xff0c;所以我就进行了一系列的测试&#xff0c;发现真的非常的好用。我们同样使用一些…

学习Java的Day27

今天学习的主要内容是在IntelliJ IDEA开发环境中&#xff0c;通过部署Tomcat服务器并连接MySQL数据库&#xff0c;实现了一个完整的留言板系统。这个项目涵盖了前后端开发的全流程&#xff0c;具体包括以下关键环节&#xff1a;开发环境搭建使用IntelliJ IDEA Ultimate版&#…

【计算机网络 | 第3篇】物理媒介

文章目录物理媒介介绍与物理媒体的分类&#x1f95d;成本考量引导型传输媒体&#x1f34b;引导型传输媒体&#xff1a;双绞线&#x1f34b;‍&#x1f7e9;双绞线类别双绞线的发展历程双绞线的物理限制引导型传输媒体&#xff1a;同轴电缆&#x1f34b;‍&#x1f7e9;结构组成…

golang的切片

切片 为什么需要切片 用于元素的个数不确定&#xff0c;所以无法通过数组的形式来进行统计。此时就需要切片 切片&#xff0c;也因此可以粗略地理解为动态数组数组的长度不能用变量来确定&#xff0c;这时候切片slice也就派上用场了 切片地基本介绍 切片的英文是slice切片是数组…

在labview中实现视频播放

这里分享一个迅雷的视频播放控件APlayer&#xff0c;非常的好用。具体操作步骤如下&#xff1a; 1.下载控件: 首先下载http://aplayer.open.xunlei.com/codecs.zip&#xff0c;将codecs文件解压后打开&#xff0c;按快捷键contrlA,随后contrlc复制里面所有的文件&#xff1b;…