
RecyclerView 的缓存机制是其高性能的核心。它通过四级缓存来高效地复用ViewHolder从而 减少findViewById的开销 以及 inflate 的次数实现流畅的滑动体验。RecyclerView的四级缓存按照“缓存是什么 - 存在哪里 - 特点是什么”的逻辑来阐述这样会显得条理清晰缓存级别存储位置容量限制复用条件是否需要重新onBindViewHolder核心特点一级mAttachedScrapRecycler内部不固定取决于当前屏幕内可见的Item数量屏幕内可见的ViewHolder否屏内缓存。用于布局或动画期间存储当前仍 attached 但可能被标记为“ scrap ”的ViewHolder以便快速复用。二级mCachedViewsRecycler内部默认2个可通过setItemViewCacheSize()调整刚滑出屏幕的ViewHolder且位置position必须匹配否离屏缓存。命中率最高是快速滚动的关键。缓存了完整的ViewHolder和其数据可直接复用。三级mViewCacheExtension开发者自行实现无限制由开发者定义由开发者自定义匹配规则取决于实现开发者自定义缓存。一般很少使用除非有非常特殊的缓存需求。四级mRecyclerPoolRecycledViewPool对象每个ViewType默认5个可调整任何ViewHolder按ViewType匹配是共享缓存池。允许多个RecyclerView实例共享同一个RecycledViewPool实现ViewHolder跨列表复用。⚙️ 缓存的工作流程保存流程Item滑出屏幕时ViewHolder会优先尝试存入mCachedViews。如果mCachedViews已满默认2个则根据FIFO先进先出原则将最旧的ViewHolder移出。被移出的ViewHolder会被清除数据detach然后存入mRecyclerPool中并按ViewType分类存放。获取流程需要显示新Item时RecyclerView会按照以下严格顺序尝试获取一个可用的ViewHoldermAttachedScrap一级➡️mCachedViews二级➡️mViewCacheExtension三级➡️mRecyclerPool四级➡️createViewHolder创建新的四级缓存的理解RecyclerView 的缓存机制本质上是为了复用 ViewHolder,减少 findViewById 和 inflate 的次数,它主要有四级缓存。第一层是 mAttachedScrap屏幕内缓存,也就是屏幕内还在显示的 ViewHolder, 只是数据变了直接会将其重新绑定数据。第二层缓存是 mCachedViews,也就是缓存刚滑出屏幕的 ViewHolder如果用户划出后又立马划回来会直接复用, 默认大小是 2,复用时一般不会走 onCreateViewHolder()。第三层是 ViewCacheExtension,这个是留给开发者自定义的,用得比较少。第四层是 RecycledViewPool,也就是缓存池,按 ViewType 类型存放划出很远的 ViewHolder,不同的 RecyclerView 之间还可以共享这个池子。当需要新的 Item 时,会依次从这四级里查找,都没命中才会走 onCreateViewHolder() 创建新的 ViewHolder,所以整体来说,RecyclerView 性能好的核心就在于尽可能复用已有的 ViewHolder,减少对象创建和 GC 压力,保证列表滑动的流畅。一个流程的理解整个流程记成四步,第一,创建 RecyclerView,当 RecyclerView 显示时,它会向适配器要当前位置的 item,如果没有可复用的 ViewHolder,就调用 onCreateViewHolder,也就是解析 item.xml创建 ViewHolder。第二步,绑定数据,当 ViewHolder 创建好后,就调用 onBindViewHolder,把当前位置的数据绑定到这个 ViewHolder 上,比如说一号 ViewHolder绑定第零条数据,二号 ViewHolder绑定第一条数据,以此类推,直到填满当前屏幕。第三步,开始滑动,当第零个 item 滑出屏幕,它的 ViewHolder 不会被销毁,而是进入缓存。接着要显示新的第十个 item 时,系统会先优先查看缓存,如果有合适的 ViewHolder 就直接拿来用,不会重新创建。第四步,重新绑定数据。这时还是调用 onBindViewHolder,把第十条数据绑定到刚才复用的 ViewHolder 上,所以同一个 ViewHolder 可能先显示第零条数据,再显示第十条,第二十条,但 TextView、ImageView这些子 View 都是同一套对象。一句话总结就是少量 ViewHolder 加反复绑定新数据,达到高效列表。