RecyclerView的回收复用机制解密
前言
学习源码,研究源码编程思想,是程序开发者进阶的必经之路。然而,进了源码世界,就像是进了迷失森林,没有地图,迟早要死在里面。有个地图会好很多。
此类文集,专门用图解编程的方式,来讲解一个知识点,从一个点切入,理解切入点之后,再进行知识发散。
路漫漫,进阶之路不好走。与众君共勉之。
正文
大家都知道RecyclerView
有回收复用机制,那么回收复用机制是如何作用的?
回收复用,细分下来,是两个概念: 回收 和 复用 有如下几个问题。
回收的是什么?复用的又是什么?
回收到哪里去了?复用又是从哪里拿?
什么时候回收?什么时候复用?
图解编程
看图之前,先明确一个概念,
RecyclerView
是支持滑动,那么一定可以确定一点------回收和复用一定是基于滑动事件的,不然一个静止的view
,谈不上回收复用.
既然如此,那么我们探索的起点,应该是RecyclerView
的onTouchEvent
的move
事件
回收:当一个
itemView
从可见到不可见时,RecyclerView
利用回收机制,将它存放到了内存中,以便其他item
出现时,不用每次都去new
一个新的itemView
,而是只去onBindViewHolder
绑定数据就行了.大概流程如下:
回收过程
复用:滑动过程中出现了新的itemView,不用每次都去new,而是优先从缓存中去拿,缓存不能满足需求,再去 执行onCreateViewHolder创建新的itemView并封装到viewHolder中
大概流程如下:
Rv复用过程.jpg
如果追踪一遍上面的源码,那么就可以回答之前的问题
回收的是什么?复用的又是什么?
回收到哪里去了?复用又是从哪里拿?答:回收和复用的都是
ViewHolder
对象,在RecyclerView
的内部类Recycler
中,可以看到四重缓存中的关键数据结构都和ArrayList<ViewHolder>
有关,ViewHolder
是itemView
的封装。
说明无论回收还是复用,都是以ViewHolder
为单位去存取。
什么时候回收?什么时候复用?
答:我们追踪程序,是以
RecyclerView
的onTouchEvnet
move
事件为起点。结合追踪到的源码,可以发现,回收发生在itemView
消失的时候,复用则发生在itemView
由不可见到可见的时候
其他重要结论
RecyclerView
本身只是一个容器(RecyclerView extends ViewGroup
), 它的onLayout
方法重写,决定了itemView
的排布方式,追踪进去,onLayout
==>dispatchLayout()
==>dispatchLayoutStep1()
dispatchLayoutStep2()
dispatchLayoutStep3();
看来layout
过程分为三步,而进入这3个方法,都能找到mLayout.XXX
方法,这是因为RecyclerView
本身只是一个ViewGroup
,它的布局方式,全权委托给了LayoutManager
这个内部类的实现,而这个实现的关键方法
则是:onLayoutChildren
,重写这个方法将会决定RecyclerView
的itemView
如何布局
看过了源码,在去理解之前写的一些
RecyclerView
的Adapter
,认识深刻了很多,为什么它有这么几个方法onCreateViewHolder
,onBindViewHolder
, 为什么Adapter
的类定义时要这样Adapter<VH extends ViewHolder>
. 因为Adapter
是RecyclerView
的数据和itemView
的连接层,itemView
都是要封装到ViewHolder
中的,绑定数据就要和ViewHolder
发生关系
RecyclerView
这个东西,如果看成是一个知识体系,那么它有这么几个关键因素:
1. 容器 ,RecyclerView
本身
2. 布局管理器,RecyclerView.LayoutManager
3. 回收复用机制,RecyclerView.Recycler
4. 适配器,RecyclerView.Adapter
当然,它的内部类当然不止这么几个,各有各的作用,今天探索复用机制,就涉及到了这么几个。