android recyclerview缓存2_四级缓存机制

RecyclerView 的缓存机制设计得非常精妙,主要分为 四级缓存机制,用来实现「滑动流畅」与「避免重复创建 ViewHolder」。


🧩 一、RecyclerView 的四级缓存机制

RecyclerView 内部的缓存体系主要存在于 Recycler 对象中,它有 4 级缓存层次

缓存级别 缓存位置 缓存内容 命中条件 是否需要重新绑定数据
1️⃣ Scrap 缓存 mAttachedScrap / mChangedScrap 当前屏幕中暂时被移除但仍附着的 ViewHolder position 相同 不需要
2️⃣ Recycler 缓存池 mCachedViews 刚刚离开屏幕的 ViewHolder(仍与 Adapter 数据对应) position 相同 可能需要绑定(如果数据变化)
3️⃣ ViewCacheExtension(可选) 自定义缓存逻辑 自定义 ViewHolder 缓存策略 自定义 可自定义是否重新绑定
4️⃣ RecycledViewPool(共享池) RecycledViewPool 可复用的 ViewHolder(按 viewType 分类) viewType 相同 需要重新绑定

🧠 二、缓存机制的工作流程

假设 RecyclerView 滑动时有一个 item 被移出屏幕,那么流程如下:

🔹 1. 从屏幕上移除

当一个 Item 滑出屏幕:

  • RecyclerView 会先尝试把对应的 ViewHolder 放入 mCachedViews
  • 如果 mCachedViews 已经满(默认容量是 2),则最旧的 ViewHolder 会被移入 RecycledViewPool

🔹 2. 获取可复用的 ViewHolder

当 RecyclerView 需要显示一个新的 item 时,会按以下顺序查找缓存:

1️⃣ mAttachedScrap / mChangedScrap

  • 如果 item 仍在屏幕中(比如执行动画时),会从这里直接取出。

2️⃣ mCachedViews

  • 如果滑动回到刚刚移出屏幕的 item,通常能直接命中,极快。

3️⃣ ViewCacheExtension(如果开发者自定义了)

  • 提供更灵活的缓存机制。

4️⃣ RecycledViewPool

  • 如果前几级都找不到,会从全局池中根据 viewType 获取可复用的 ViewHolder。

5️⃣ 最终创建新 ViewHolder

  • 如果四级缓存都 miss,则调用 Adapter 的 onCreateViewHolder() 重新创建。

🪣 三、各缓存的关系图

复制代码
Recycler
 ├── mAttachedScrap          // 屏幕中可见或刚移除的ViewHolder
 ├── mCachedViews (size=2)   // 最近离开的item缓存
 ├── ViewCacheExtension      // 开发者自定义缓存扩展
 └── RecycledViewPool        // 全局池(按viewType存放)

⚙️ 四、RecycledViewPool 的意义

RecycledViewPool 是可 在多个 RecyclerView 之间共享的缓存池

例如 ViewPager+RecyclerView 或多 Tab 列表场景,可以让不同 RecyclerView 共享 ViewHolder,减少重复创建的开销:

kotlin 复制代码
val pool = RecycledViewPool()
recyclerView1.setRecycledViewPool(pool)
recyclerView2.setRecycledViewPool(pool)

可以通过以下方法设置每种类型的最大缓存数:

kotlin 复制代码
pool.setMaxRecycledViews(VIEW_TYPE_ITEM, 10)

🧮 五、关键源码位置(理解加分)

主要类:

  • RecyclerView.Recycler(负责回收与复用逻辑)
  • RecyclerView.RecycledViewPool(全局缓存池)
  • Adapter.createViewHolder() / bindViewHolder()

核心方法:

  • Recycler.getViewForPosition()
  • Recycler.tryGetViewHolderForPositionByDeadline()

✅ 六、总结对比表

缓存层级 存放位置 特点 命中率 是否重新bind
mAttachedScrap 当前屏幕内 临时存放
mCachedViews 最近离屏 数量有限(2) 有时
ViewCacheExtension 可选自定义 灵活 不定 自定义
RecycledViewPool 全局共享 按类型分池

💡 面试高分总结回答模板:

RecyclerView 采用四级缓存机制来提高复用率与滑动性能,分别是:

  1. Scrap 缓存:缓存当前屏幕中临时移除的 ViewHolder。
  2. Cached 缓存:缓存刚离开屏幕的少量 ViewHolder。
  3. ViewCacheExtension:开发者可自定义缓存逻辑。
  4. RecycledViewPool:按 viewType 分类的全局复用池,可多个 RecyclerView 共享。

当 RecyclerView 需要新的 View 时,会依次从这些缓存中查找可复用的 ViewHolder,若找不到才创建新的。

这套机制极大地提升了性能,避免了频繁创建 View 和调用 onCreateViewHolder() 的开销。


相关推荐
雨辰AI4 小时前
生产级实测:SpringBoot3 + 达梦数据库接口从 200ms 优化至 20ms 完整调优指南
java·数据库·spring boot·后端·政务
ltlovezh5 小时前
ROI 编码学习指南:Android 与 FFmpeg 的真实实现边界
android·ffmpeg·音视频开发
砍材农夫6 小时前
物联网实战|Spring Boot + Netty 搭建 MQTT 消息路由与流转层
java·spring boot·后端·物联网·spring
心前阳光6 小时前
Unity之2021.3.45f2c1发布安卓程序遇到的问题
android·unity·游戏引擎
Saniffer_SH7 小时前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
lazy H7 小时前
Spring Boot 项目如何连接 Redis?新手入门配置和常见错误总结
ide·spring boot·redis·后端·学习·intellij-idea
SXJR7 小时前
spring boot + langchain4j +milvus实现向量存储
java·spring boot·后端·大模型·milvus·rag·langchain4j
王木风7 小时前
Spring Boot + LLM 工程化:把短视频流水线拆成 16 个独立角色的踩坑记录
人工智能·spring boot·后端·开源·新媒体运营·音视频·agent
utf8mb4安全女神7 小时前
MySQL5.7升级到MySQL8.0并进行数据迁移
android
黄林晴7 小时前
Android XR DP4 重磅发布:手机 App 直投眼镜,Compose 原生玩转 3D 内容
android·google io