当前位置: 首页 > 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.lryc.cn/news/615413.html

相关文章:

  • 202506 电子学会青少年等级考试机器人六级器人理论真题
  • 【自动化运维神器Ansible】playbook自动化部署Nginx案例解析:助力从零构建高效Web服务
  • Kettle ETL 工具存在的问题以及替代方案的探索
  • AWT 事件监听器深入浅出:Action/Mouse/Key/Window 全解析与实战
  • B2.0:对硬件学习的一些个人心得感悟
  • 跨境电商系统开发:ZKmall开源商城的技术选型与代码规范实践
  • Linux 中CentOS Stream 8 - yum -y update 异常报错问题
  • MySQL 主备(Master-Slave)复制 的搭建
  • 每日五个pyecharts可视化图表-line:从入门到精通
  • 基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
  • 计算机系统设计中都有什么任务~计算密集~IO密集~逻辑密集等
  • 通过 Docker 运行 Prometheus 入门
  • 如何在 Excel 中快速求和?【图文详解】Excel求和技巧,Excel求和公式大全,多种方式求和
  • 轻松Linux-5.进程控制
  • drippingblues靶机
  • Easysearch 冷热架构实战
  • 从 AI 到实时视频通道:基于模块化架构的低延迟直播全链路实践
  • Docker容器lnmp平台部署discuz论坛
  • 配送算法10 Batching and Matching for Food Delivery in Dynamic Road Networks
  • 算法篇----分治(快排)
  • Java 大视界 -- Java 大数据在智能医疗手术机器人操作数据记录与性能评估中的应用(390)
  • 【能碳建设1】用AI+开源打造物联网+能碳管理+交易SaaS系统的最短路径实施指南
  • Mac屏幕取色不准?探究原理和换算规则
  • C++四种类型转换
  • 97-基于Python的大众点评数据分析预测系统
  • react之React.cloneElement()
  • flex布局初体验
  • 低速CAN 高速CAN是否兼容?
  • react 常用组件库
  • 基于遗传优化的稀疏线阵最优排布算法matlab仿真