当前位置: 首页 > news >正文

RecyclerView 缓存机制

一、四级缓存体系

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.dtcms.com/a/323092.html

相关文章:

  • centos 怎么将一些命令设置为快捷命令
  • 2025华数杯数学建模C题:可调控生物节律LED光源全解析
  • LLM表征的提取方式
  • 【Python 高频 API 速学 ⑥】
  • 【Mac】MLX:Lora微调工作流
  • 【排序算法】①直接插入排序
  • QT第二讲-信号和槽
  • uniapp实现的圆形滚盘组件模板
  • ThingsBoard配置邮件发送保姆级教程(新版qq邮箱)
  • SkyWalking-2--Java Agent是什么?
  • Qt与嵌入式设备中的字节序问题
  • 客服Agent革命:智能客服系统的技术实现与效果评估
  • 八、《DaaS(设备即服务):企业轻资产化新路径》--从97.4%首期投入削减到AI算力高效迭代的范式革命
  • ​​​​​​​【Datawhale AI夏令营】多模态RAG财报问答挑战赛:学习笔记与上分思考
  • “黑影御剑飞行”视频引发的思考
  • 差分放大电路的四种接法
  • react-window
  • 组合期权:垂直价差
  • Playwright C# 自动登录并上传 Excel 文件 的可运行示例
  • Java 数据类型与内存模型:从字节到引用的底层逻辑
  • 数字图像处理基础——opencv库(Python)
  • C语言库中的字符函数
  • 基于 RAUC 的 Jetson OTA 升级全攻略
  • Vue和Springboot初步前后端分离建立项目连接(解决前后端跨域问题)
  • linux安装php
  • 机器学习 K-Means聚类 无监督学习
  • AI 算法优化实战指南:从理论到部署的全流程优化策略
  • VSCode添加Python、Java注释技巧、模板
  • 企业级web应用服务器TOMCAT入门详解
  • 2G内存的服务器用宝塔安装php的fileinfo拓展时总是卡死无法安装成功的解决办法