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


相关推荐
BoomHe32 分钟前
Now in Android 架构模式全面分析
android·android jetpack
用户8307196840822 小时前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解3 小时前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解3 小时前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记7 小时前
Spring Boot Web MVC配置详解
spring boot·后端
二流小码农8 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少8 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker8 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋9 小时前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我1 天前
让我们实现一个更好看的内部阴影按钮
android·flutter