Recyclerview的缓存机制

RecyclerView是Android中用于替代ListView的组件,具有强大的可扩展性。它支持线性、网格和瀑布流布局,并提供OnItemTouchListener实现复杂交互。局部刷新通过notifyItem*方法提升效率。RecyclerView的缓存机制包括屏幕内缓存、屏幕外缓存、自定义缓存和缓存池。屏幕外缓存默认存储2个ViewHolder,RecycledViewPool根据ViewType缓存最多5个。开发者可自定义ViewCacheExtension扩展缓存。了解这些机制有助于优化RecyclerView性能。

前言

Android新增的Recyclerview主要用于代替ListView。Recyclerview可扩展性强。

  • 可以通过LayoutManager形成线性(横向与竖向)、网格、瀑布流布局。
  • 通过OnItemTouchListener监听 Item 的事件,虽然比ListView.OnItemClickListener麻烦了点,但是可以实现更复杂的功能,比如item滑动。
  • 提供了notifyItemInserted、notifyItemRemoved、notifyItemChanged、notifyItemMoved来提高局部刷新的效率。
  • 没有ListView那种 HeaderView 和 FooterView , 但可以通过来 getItemViewType来生成不同的视图。
  • RecyclerView还定义了ViewHolder,配合RecyclerView.Adapter,封装重用ItemView的逻辑,还有四级缓存,效率大大增加。

Recyclerview的缓存类

RecyclerView缓存基本上是通过三个内部类管理的,Recycler、RecycledViewPool和ViewCacheExtension。

Recycler

用于管理已经废弃或者与RecyclerView分离的ViewHolder,为了方便理解这个类,整理了下面的资料,内部类的成员变量和他们的含义:

变量作用
mChangedScrap与RecyclerView分离的ViewHolder列表
mAttachedScrap未与RecyclerView分离的ViewHolder列表
mCachedViewsViewHolder缓存列表
mViewCacheExtension开发者可以控制的ViewHolder缓存的帮助类
mRecyclerPoolViewHolder缓存池

RecycledViewPool

RecycledViewPool类是用来缓存Item用,是一个ViewHolder的缓存池,如果多个RecyclerView之间用setRecycledViewPool(RecycledViewPool)设置同一个RecycledViewPool,他们就可以共享Item。其实RecycledViewPool的内部维护了一个Map,里面以不同的viewType为Key存储了各自对应的ViewHolder集合。可以通过提供的方法来修改内部缓存的Viewholder。

ViewCacheExtension

开发者可自定义的一层缓存,是虚拟类ViewCacheExtension的一个实例,开发者可实现方法getViewForPositionAndType(Recycler recycler, int position, int type)来实现自己的缓存。

Recyclerview的四级缓存

1.屏幕内缓存

屏幕内缓存指在屏幕中显示的ViewHolder,这些ViewHolder会缓存在mAttachedScrap、mChangedScrap中 :

  • mChangedScrap 表示数据已经改变的viewHolder列表
  • mAttachedScrap 未与RecyclerView分离的ViewHolder列表

2.屏幕外缓存

当列表滑动出了屏幕时,ViewHolder会被缓存在 mCachedViews ,其大小由mViewCacheMax决定,默认DEFAULT_CACHE_SIZE为2,可通过Recyclerview.setItemViewCacheSize()动态设置。

3.自定义缓存

可以自己实现ViewCacheExtension类实现自定义缓存,可通过Recyclerview.setViewCacheExtension()设置。

4.缓存池

ViewHolder在首先会缓存在 mCachedViews 中,当超过了个数(比如默认为2), 就会添加到 RecycledViewPool 中。RecycledViewPool 会根据每个ViewType把ViewHolder分别存储在不同的列表中,每个ViewType最多缓存DEFAULT_MAX_SCRAP = 5 个ViewHolder,如果RecycledViewPool没有被多个RecycledView共享,对于线性布局,每个ViewType最多只有一个缓存,如果是网格有多少行就缓存多少个。他们之间的关系如下 :

缓存策略

Recyclerview在获取ViewHolder时按四级缓存的顺序查找,如果没找到就创建。其中只有RecycledViewPool找到时才会调用 bindViewHolder,其它缓存不会重新bindViewHolder 。 流程如下 :

总结

通过了解RecyclerView的四级缓存,我们可以知道,RecyclerView最多可以缓存 N(屏幕最多可显示的item数) + 2 (屏幕外的缓存) + 5*M (M代表M个ViewType,缓存池的缓存),只有RecycledViewPool找到时才会重新调用 bindViewHolder。
还需要注意的是,RecycledViewPool 可以被多个RecyclerView共享,其缓存个数与ViewType个数、布局相关,如果RecycledViewPool没有被多个RecycledView共享,对于线性布局,每个ViewType最多只有一个缓存,如果是网格布局有多少行就缓存多少个。

参考

# Android

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值