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() 的开销。


相关推荐
qq_297574674 小时前
【实战教程】SpringBoot 集成阿里云短信服务实现验证码发送
spring boot·后端·阿里云
STCNXPARM5 小时前
Android camera之硬件架构
android·硬件架构·camera
RANCE_atttackkk5 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
韩立学长6 小时前
【开题答辩实录分享】以《智能大学宿舍管理系统的设计与实现》为例进行选题答辩实录分享
数据库·spring boot·后端
2501_944525546 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
he___H7 小时前
Redis高级数据类型
数据库·redis·缓存
松☆8 小时前
Dart 核心语法精讲:从空安全到流程控制(3)
android·java·开发语言
大佐不会说日语~8 小时前
使用Docker Compose 部署时网络冲突问题排查与解决
运维·网络·spring boot·docker·容器
惊讶的猫9 小时前
Redis双写一致性
数据库·redis·缓存
_李小白9 小时前
【Android 美颜相机】第二十三天:GPUImageDarkenBlendFilter(变暗混合滤镜)
android·数码相机