RecyclerView缓存机制

RecyclerView作为常用的列表类需求开发的控件之一,已经成为我个人开发项目时的首选。其扩展性要远强于ListView。RecyclerView的缓存机制通常也是面试必考的的内容之一,本文就此做一个整理。

一、四级缓存

如果说RecyclerView和ListView在缓存机制上有什么不同,一定要知道RecyclerView是四级缓存,而ListView是两级缓存。上代码

其中,一级缓存mAttachedScrap,二级缓存mCachedViews,三级缓存mViewCacheExtension,四级缓存mRecyclerPool。

追进getViewForPosition方法,可以看到最终进入了tryGetViewHolderForPositionByDeadline方法。在里面注释写到ViewHolder的内容来自scrap,cache,pool或者create。

先看里面方法第一次尝试获取holder。是图中的getScrap....方法(名字实在是长)不过通过命名我们可以得知,是从scrap或者hiddenChilden或者cache里获取。

在此方法中,是按照scrap,children,cache的顺序获取的。scrap中如果有,会把这个holder添加上returnFromScrap的标记。scrap中如果没有,会获取children中的。值得一提的是children中符合要求的holder会被放进scrap中。最后再从cache中获取。其中从children中获取和cache中获取,均由参数dryRun控制影响,如果为true,则不会从children中获取,并且cache中获取后不会remove其中的holder。

第二次尝试获取。

第一次获取失败后,holder仍然为null,会继续走下面的代码。

可以看到第二次获取时,会先拿到type,也就是第一次获取时是不区分type的。之后跟进getScrapOrCachedViewForId方法。

在此方法中,是对获取的holder增加了id,type以及dryRun的校验,不符合要求的仍然无法使用,会把holder置为null。

第三次尝试。

从代码中看出,第三次尝试是根据mViewCacheExtension来获取。这个是自定义缓存。这个view通过setViewCacheExtension来设置,之后便可使用。使用时需要实现它的getViewForPositionAndType方法。一般不太常用,有兴趣可以试试。

第四次尝试。

看代码中的注释可知,这次是从Pool里拿。

getRecycledViewPool是recyclerView提供的获取RecycledViewPool的方法,这个pool,注解中说明是用来支持多个recyclerview共享view的。其本身是一个静态内部类。

在pool的内部,定义了一个类为ScrapData,这个类里面持有一个viewHolder的arrayList,默认大小是5,也就是ArrayList最多放5个ViewHolder。而外部使用SparseArray来存放ScrapData类,这个没有数量限制。

第五次尝试。创建

之前获取都不成功,说明没有缓存可以使用了,于是只好自己来。

里面的关键行代码,mAdapter.createViewHolder,是不是很熟悉。就是我们定义Adapter时所重写的方法。这里就是新创建一个ViewHolder了。

总结一下,缓存是四级缓存,scrap,cache,viewExtension,以及pool。

第一次获取,从scrap和cache中获取,只看是否可用。第二次获取还是从scrap和cache获取,但是要考虑id和type匹配。第三次获取是自定义缓存获取,考虑type。第四次是从pool中获取,考虑type。第五次是创建。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值