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方法里,重置属性动画的属性,比如角度、透明度等。

相关推荐
wei_shuo26 分钟前
飞算 JavaAI 开发助手:深度学习驱动下的 Java 全链路智能开发新范式
java·开发语言·飞算javaai
熊猫钓鱼>_>26 分钟前
用Python解锁图像处理之力:从基础到智能应用的深度探索
开发语言·图像处理·python
GO兔37 分钟前
开篇:GORM入门——Go语言的ORM王者
开发语言·后端·golang·go
欧阳秦穆1 小时前
apoc-5.24.0-extended.jar 和 apoc-4.4.0.36-all.jar 啥区别
java·jar
好开心啊没烦恼1 小时前
Python 数据分析:numpy,抽提,整数数组索引与基本索引扩展(元组传参)。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy·pandas
岁忧1 小时前
(LeetCode 面试经典 150 题 ) 58. 最后一个单词的长度 (字符串)
java·c++·算法·leetcode·面试·go
Java初学者小白1 小时前
秋招Day14 - Redis - 应用
java·数据库·redis·缓存
代码老y1 小时前
Spring Boot + 本地部署大模型实现:优化与性能提升
java·spring boot·后端
GodKeyNet1 小时前
设计模式-桥接模式
java·设计模式·桥接模式
奈斯ing1 小时前
【Redis篇】数据库架构演进中Redis缓存的技术必然性—高并发场景下穿透、击穿、雪崩的体系化解决方案
运维·redis·缓存·数据库架构