Recyclerview缓存原理

一、Recyclerview列表视图的构建过程

Recyclerview主要是有itemview组成,而itemview的构建过程主要分为以下三步:

1、Create ViewHolder

2、Bind ViewHolder

3、Render ViewHolder

其中,第一步的创建ViewHolder是视图构建最耗时的操作,Recyclerview为了优化减少ViewHolder创建的次数,

采取了两级缓存复用。

二、Recyclerview的两级缓存

1、缓存区

缓存区(mCachedViews)默认大小为2,可以根据实际业务需要修改大小。缓存区是用来存储最近离开屏幕的ViewHodler,由于用户的滚动或抖动,这些item更容易被重新显示,所以这些ViewHolder的状态和数据都没有被重置,方便再次显示的时候不需要重复走构建流程的第1、2步,即不走Create和Bind方法。如果缓存区满了,但是还有新的ViewHolder需要回收,这个时候就会用到缓存池(mRecyclerPool)。

2、缓存池

当缓存区满,新的ViewHolder会被放入到缓存区,而最先放入缓存区的ViewHolder会被放入到缓存池中。放入到缓存池的ViewHolder的数据会被重置,相当于解绑。缓存池的ViewHolder会根据ViewType分别存储,默认情况下每个ViewType存储5个ViewHolder,这个数值可以修改。从缓存池中取出复用的ViewHolder,不需要重走构建流程的第一步,也就是不用走Create方法。

三、Recyclerview的复用逻辑

由于缓存区里的ViewHolder保存了状态和数据,并且是最靠近显示区域的,所以当需要使用VIewHolder的时候,优先从缓存区里查找VIewHolder。如果缓存区没有合适的,就会去缓存池里根据ViewType进行查找。如果缓存池也没有找到合适的VIewHolder,那就只能走Create和Bind方法新创建一个VIewHolder。

四、ViewType的目的

在Recyclerview中使用VIewType的目的是为了区分不同的Item视图结构。缓存池根据ViewType分别存储也是为了

耗时,因为缓存池不区分不同的视图样式的话,复用ViewHodler时就会出现因为视图样式不一样而需要重新布局的耗时操作。

五、缓存机制失效的情况

1、缓存机制失效原因

通过查看Recyclerview的源码可以发现,是否回收VIewHolder的判断条件有两个,分别是boolean类型的forceRecycle和isRecyclable方法。在isRecyclable方法里,对ViewCompat.hasTransientState(itemView)方法的返回值取反,也就是说该方法返回值如果为true,那isRecyclable的返回值就是false。在hasTransientState方法里是判断TransientState的值,这个值是在VIewHolder中view属性动画开始和结束的时候被设置的,分别设为true和false。从上面的逻辑可以看出,如果一个ViewHolder在离开显示区域时,它的内部有一个属性动画在执行的话,就会导致isRecyclable返回false,从而不会回收这个ViewHolder。

2、解决办法

在forceRecycle的取值中,它会根据onFailedToRecyclerView方法的返回值设定,我们可以重写该方法,达到强制缓存的目的。同时,我们还需要在Bind方法里,重置属性动画的属性,比如角度、透明度等。

相关推荐
m0_74824802几秒前
Redis使用手册
java
Kerwin要坚持日更1 分钟前
一文讲解Redis中的主从复制
数据库·redis·缓存
Suk-god2 分钟前
【Redis】基础知识入门
数据库·redis·缓存
CoderCodingNo3 分钟前
【GESP】C++二级真题 luogu-b3924, [GESP202312 二级] 小杨的H字矩阵
java·c++·矩阵
2501_9032386527 分钟前
Spring MVC中环境配置的实战应用
java·spring·mvc·个人开发
奔跑吧邓邓子29 分钟前
【Python爬虫(34)】Python多进程编程:开启高效并行世界的钥匙
开发语言·爬虫·python·多进程
程序员侠客行29 分钟前
Spring事务原理详解 三
java·后端·spring·架构
Heris991 小时前
2.22 c++练习【operator运算符重载、封装消息队列、封装信号灯集】
开发语言·c++
----云烟----1 小时前
C/C++ 中 volatile 关键字详解
c语言·开发语言·c++
mjr1 小时前
设计模式-Java
java·设计模式