RecyclerView缓存复用的理解

663 阅读3分钟

recyclerview与listview相比最大的优点在于解构,更利于自定义,利于扩展。如布局方式layoutmanager、分割线,可以实现更复杂的UI要求。

recyclerview实现了四级缓存:1.attachedscrap屏幕内缓存;2.cacheviews滑出页面缓存;3.cacheextensionview自定义缓存;4recyclerpool缓存池缓存。

attachedscrap用于屏幕内item的复用,不需要bindview和createview。 cacheview会缓存最新的滑出屏幕的两个item,实现页面轻微滑动不需要重新bindview和createview。 cacheextensionview默认是没有实现的,如果有需求开发者自己实现(一般不需要处理)。 recylerpool缓存池缓存,这里的item是清除数据的,复用需要重新bindview。

复用。 当用户滑动recyclerview的时候,1.缓存系统首先会从页面内根据ID和position获取itemview,如果获取失败;2.那么缓存系统会从二级缓存cacheview中根据ID和position获取itemview,如果获取失败,3.会从recyclerpool获取item,此时是根据itemtype获取的,如果recyclerpool中存在对应类型的item则返回并调用bindview操作实现复用,否则会调用adapter.createview创建一个item。

缓存: 当用户入recyclerview页面,1.首先attachedscrap屏幕内缓存会保存屏幕内item,实现一级缓存。2.用户滑动recyclerview的时候,最新滑出屏幕的item会缓存到二级缓存cacheview中(注意,必须完全滑出屏幕才会),此时缓存的itemview是绑定着数据,如果用户反向滑动,则可以直接根据ID和position复用。3.当二级缓存大小超过2的时候,会触发四级缓存recyclerpool。当第三个滑出屏幕的item向二级缓存插入的时候,cacheview会从保存的数组中取出最最老的一个item将其绑定的数据清除,根据itemtype投放到对应的recyclerpool中,然后删掉,并把新缓存item插入最前面。

cacheview和recyclerpool底层实现缓存的数据结构:

cacheview底层用一个arraylist保存缓存的item,最大为2,当超过2的时候,会把第0个位置上投向四级缓存并删除,则原来1位置的item位置变为0,然后新item,放入位置1。也就是说优先缓存新的旧数据会被删除。

recyclerpool底层是sparesarray,key值是一个个itemtype,value值是一个arraylist数组,sapresarray可以任意长,而value中的arraylist最大为5,超过5则不接受。也就是说,itemtype可以任意多,但是每个itemtype类型最多可以接受5个缓存。

复用和缓存触发时机主要是加载(setadapter)和滑动的时候。

RecyclerView的优化:1.在bindView中不要做耗时的操作如日期格式化等,因为要经常调用;2.尽量使用局部刷新如新增和删除item的时候,甚至单独刷新某一个控件;3.修改缓存的大小如二级缓存cacheview大小可以改大点,以空间换效率;4.RecyclerView嵌套使用的时候,如果item是一样的可以使用一个缓存池;