RecyclerView缓存原理及优化方向

2020-06-26  本文已影响0人  凯玲之恋

前沿

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

1. RecyclerView缓存机制与性能优化关系

RecyclerView做性能优化要说复杂也复杂,比如说布局优化,缓存,预加载等等。

其优化的点很多,在这些看似独立的点之间,其实存在一个枢纽:Adapter。

因为所有的ViewHolder的创建和内容的绑定都需要经过Adaper的两个函数onCreateViewHolder和onBindViewHolder

因此我们性能优化的本质就是要**减少这两个函数的调用时间和调用的次数**

如果我们想对RecyclerView做性能优化,必须清楚的了解到我们的每一步操作背后,onCreateViewHolder和onBindViewHolder调用了多少次。

因此,了解RecyclerView的缓存机制是RecyclerView性能优化的基础。


1655326cbdee046f.png

2. 绘制原理简述

2.1 假设

为了简化问题,绘制原理介绍提供以下假设:

2.2 绘制过程

(1)类的职责介绍
LayoutManager:接管RecyclerView的Measure,Layout,Draw的过程

Recycler:缓存池

Adapter:ViewHolder的生成器和内容绑定器。

(2)绘制过程简介

3. 缓存机制

3.1 Recyclerview的缓存类

RecyclerView缓存基本上是通过三个内部类管理的,RecyclerRecycledViewPoolViewCacheExtension
Recycler
用于管理已经废弃或者与RecyclerView分离的ViewHolder,为了方便理解这个类,整理了下面的资料,内部类的成员变量和他们的含义:

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

RecycledViewPool
RecycledViewPool类是用来缓存Item用,是一个ViewHolder的缓存池,如果多个RecyclerView之间用setRecycledViewPool(RecycledViewPool)设置同一个RecycledViewPool,他们就可以共享Item。
其实RecycledViewPool的内部维护了一个Map,里面以不同的viewType为Key存储了各自对应的ViewHolder集合。可以通过提供的方法来修改内部缓存的Viewholder。
ViewCacheExtension
开发者可自定义的一层缓存,是虚拟类ViewCacheExtension的一个实例,开发者可实现方法getViewForPositionAndType(Recycler recycler, int position, int type)来实现自己的缓存。

3.2 Recyclerview的四级缓存

3.2.1 屏幕内缓存

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

3.2.2 屏幕外缓存

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

3.2.3 自定义缓存

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

3.2.4 缓存池

ViewHolder在首先会缓存在 mCachedViews 中,当超过了个数(比如默认为2), 就会添加到 RecycledViewPool 中。
在有限的mCachedViews中如果存不下ViewHolder时,就会把ViewHolder存入RecyclerViewPool中。
* 按照Type来查找ViewHolder
* 每个Type默认最多缓存5个

RecycledViewPool 会根据每个ViewType把ViewHolder分别存储在不同的列表中,每个ViewType最多缓存DEFAULT_MAX_SCRAP = 5 个ViewHolder,如果RecycledViewPool没有被多个RecycledView共享,对于线性布局,每个ViewType最多只有一个缓存,如果是网格有多少行就缓存多少个。


1155837-c10b3fce7c974aee.png

3.3 缓存策略

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

1155837-e5365d4a8d217428.png

3.4 总结

通过了解RecyclerView的四级缓存,我们可以知道,RecyclerView最多可以缓存 N(屏幕最多可显示的item数) + 2 (屏幕外的缓存) + 5*M (M代表M个ViewType,缓存池的缓存),只有RecycledViewPool找到时才会重新调用 bindViewHolder。

RecyclerView在Recyler里面实现ViewHolder的缓存,Recycler里面的实现缓存的主要包含以下5个对象:

3.2 缓存机制图解

RecyclerView在设计的时候讲上述5个缓存对象分为了3级。
每次创建ViewHolder的时候,会按照优先级依次查询缓存创建ViewHolder
三级缓存分别是:

3. RecyclerView性能优化方向总结

1655326cbe18dc01.png

参考

RecyclerView缓存原理,有图有真相
关于Recyclerview的缓存机制的理解

上一篇 下一篇

猜你喜欢

热点阅读