缓存
RecyclerView的缓存:( tryGetViewHolderForPositionByDeadline这个方法)
-
mAttachedScrap第一级缓存,用于快速重现屏幕上的ViewHolder。主要是用来存放ViewHolder兑现的ArrayList,这一级缓存没有容量限制,这里的数据不做修改,不会重走Adapter的绑定方法(ViewHolder视图还在屏幕中)
-
mChangedScrap这个变量和上面的mAttachedScrap一样,唯一不同的是这里存放的是发生了变化的Viewholder,如果使用这里发生变化的ViewHolder需要重走Adapter的绑定数据方法(ViewHolder视图还在屏幕中)
-
mCacheViews这里同样是一个存放ViewHolder的ArrayList,这里存放的是dettach掉的视图,它里面存放的已经remove掉的视图(滚出屏幕),已经和RecyclerView分离关系的视图,但它里面的ViewHolder依然保存着之前的信息数据,这一级缓存默认是缓存两个(有容量限制),
可以通过setItemViewCacheSize(5)
方法修改容量 -
mViewCacheExtension 是一个抽象静态类,用于充当附加的缓存池,官方没有实现,默认是null
-
RecyclerViewPool Viewholder缓存池,这里保存的ViewHolder不仅仅是removed掉的视图,而且是恢复了出厂设置的视图,任何白给你定过的痕迹都没有了,想用这里的缓存的ViewHolder那是铁定要重新走A倒塌而的绑定方法了,而且由于RecyclerView支持多布局,所里这里的缓存是按照itemType来分开存储的,每一个type默认的存储数量是
5
个 -
滑出屏幕的item首先存放在mCacheView中,如果mCacheViews中已满,也就是有两个ViewHolder视图,mCacheViews会根据FIFO的方式,将之前缓存的ViewHolder移动到RecyclerViewpool,如果RecyclerViewPool也存储到最大值,就会被遗弃
-
注意:缓存到mCacheView中的ViewHolder并不会清理相关信息(比如poisition,state等),因此刚一出屏幕的ViewHolder,再次被移回屏幕时,只要从CacheView中查找并显示即可,不需要重新绑定,而被缓存到RecyclerViewPool中的ViewHolder会被清理状态和位置信息,因此从RecyclerViewPool查找到的ViewHolder,需要重新调用bindViewHolder绑定数据
ListView的缓存
- mActiveViews 第一级缓存,这些View是布局过程开始时屏幕上的View,layout开始时这个数组被填充,layout结束,mActiveViews中的View移动到mScrapView,意义在于快速重现屏幕上课件的列表项ViewItem,而不需要重选createView和bindView
- mScrapView 第二级缓存,mScrapView是多个List组成的数据,数组的长度为viewTypeCount,每个List缓存不同类型的Item布局的View,其意义在于缓存离开屏幕的ItemView,目的是让即将进入屏幕的itemView重用,当mAdapter被更换时,mScrapViewsze被清空
RecyclerView优化
-
数据处理和视频加载分离
- 耗时的数据处理逻辑应该放在异步处理,这样Adaoter再notify改变数据的时候,ViewHolder可以操作数据与视图的绑定逻辑
-
数据优化
- 分页拉取数据时,对拉取下来的远端数据进行缓存,提升二次加载速度
- 对于新增挥着删除的数据通过DiffUtil来进行局部刷新数据,而不是一味地刷新数据
-
减少布局层级和过度绘制
- 可以通过自定义View或者更合理的设置布局来减少层级,移除不必要的背景减少过度绘制
-
减少xml文件inflate时间
- 这里的xml文件不急包括layout的xml,还包括当然玩乐的xml,xml文件inflate出itemView时通过耗时的IO操作,尤其当item的复用几率很低的情况下,随着Type的增多,这种inflate带来的损耗是相当大的,此时可以用代码去生成布局
-
减少对象的创建
- 一个稍微复杂的Item会包含大量的View,而大量的View的创建也会消耗大量的时间,所以要尽可能的简化ItemView
- 设计itenType时,对多ViewType能够共用的部分尽量设计成自定义View,煎炒View的构造和嵌套
-
使用RecyclerView的prefetch功能(预取功能), 提前处理完数据,然后将得到的itemholder缓存起来,等到真正要使用的时候直接从缓存取出来即可,默认是开启的
-
如果item高度是固定的话,可以使用
RecyclerView.setHasFixedSize(true)
来避免requestLayout浪费资源 -
滑动过程中停止数据和图片的加载
-
不弱不需要动画,把默认动画关闭来提升效率,动画再Android系统中是一个很大的开销
-
通过
RecyclerView.setItemViewCacheSize(size)
来加大RecyclerView的缓存,用控件换时间来提高滚动的流畅性 -
如果多个RecyclerView的Adapter是一样的,比如嵌套的RecyclerView存在一样的Adapter,可以通过设置
RecyclerView.setRecyclerViewPool
方法来共用一个RecyclerViewPool -
在onBindView的时候,只做绑定工作,不要创建对象
-
监听recyclerView滑动,实现列表滑动时停止加载图片,停止时再加载,glide有两个方法:
Glide.with(mContext).resumeRequests()
,
Glide.with(mContext).pauseRequests()
,如果是Picasso,则需要对相应的imageView添加tag,Picasso.get().resumeTag(tag)
,
Picasso.get().pauseTag(tag)
;
网友评论