Android RecyclerView 四级缓存机制
1、Scrap (mChangedScrap、mAttachedScrap)
涉及保存屏幕内的holder,涉及到item动画时、被notifyItemRangeChanged移除的holder保存在mChangedScrap中,被其他notify(除notifyDataSetChanged)移除的holder保存在mAttachedScrap中。mAttachedScrap在屏幕中的缓存,用于数据刷新时,不需要重新加载子ItemView,直接复用。因为每个ItemView由xml加载成为View (onCreateViewHolder方法) ,是一个深度遍历的过程,并且是通过反射来获取的每个View,这其实是一个耗时的操作。如果每个子ItemView都通过这种方法去加载,是非常不合适滴。所以需要缓存。
2、Cache (mCachedViews)
保存刚被移出屏幕的holder, 默认容量2 (可理解为上下各一个),通过position来保存,数据不变,直接复用。滑动时,该缓存一边add,一边remove。
3、Extension (mViewCacheExtension)
可自定义的缓存实现,默认空实现,基本用不上。
4、Pool (mRecyclerPool)
保存已被移出屏幕的无效的holder,默认容量5,可以自己new一个pool传进去(一般在RV嵌套时,子RV与父RV可共用同一个Pool),mRecyclerPoor保存第二级缓存中保存不了的ItemView。通过itemType来保存,每种itemType可以保存5个ItemView。
SparsArray:mScarp 默认容量为10,根据key,value的形式存储scarpdata,每个viewType 对应一个scarpData,那么数据便是ScarpData:
ArrayList<ViewHodler> mScarpHeap
int mMaxScarp
long mCreateRunningAverageNs
long mBindRunningAverageNs
mScarpHeap 主要存储的就是每个viewholder,默认大小为5,可以修改存储最大值。
最终结果就是一个RecyclerView最多能存储的ViewHolder数量是:5 * 10 = 50个