RecyclerView与ListView的对比,缓存策略,优缺点。
这道题想考察什么?
- 是否了解RecyclerView、ListView原理知识?
考察的知识点
- RecyclerView的布局效果、局部刷新、动画效果、缓存知识
- ListView的布局效果、局部刷新、动画效果、缓存知识
考生应该如何回答
RecyclerView和ListView都是用于加载大量数据的控件,用来实现列表的功能。接下来我们从布局、局部刷新、动画效果、缓存四个方面对比RecyclerView和ListView。
1.布局效果
ListView 的布局方式比较单一,只有一个纵向效果;
RecyclerView 的布局会多样一些, 线性布局(纵向布局,横向布局),表格布局,瀑布流布局,如果不能满足需求可以自定义LayoutManager布局管理器来实现各种需求。
2.局部刷新
在ListView只有全局刷新,即使只想刷新一个列表项,也要所有的列表项都更新,这是比较消耗性能的; RecyclerView中实现局部刷新十分的方便,例如调用notifyItemChanged()函数,这个得益于RecyclerView的创建列表项onCreateViewHolder和绑定数据onBindViewHolder的逻辑分离,同时也得益于缓存设计非常便利,具体关于缓存可以先阅读RecyclerView的回收复用原理一题的解答。
3.动画效果
ListView并没有实现动画效果,可以在Adapter自己实现item的动画效果;
在RecyclerView中,实现自己的动画效果有现成的API,如果我们想自定义动画效果,可以通过相应的接口实现(RecyclerView.ItemAnimator类),然后调用RecyclerView.setItemAnimator方法 (默认的有SimpleItemAnimator与DefaultItemAnimator)来设置动画;
4.缓存区别
层级不同
ListView有两级缓存,在屏幕中与屏幕外:mActivityViews 、 mScrapViews RecyclerView有四级缓存:有屏幕内的缓存Scrap,包括具体的mAttachedScrap、mChangedScrap,他们是在notify来修改数据的时候应用;有mCacheViews缓存,它用于保存离开屏幕的列表项Item;有自定义的缓存mViewCacheExtension,是缓存拓展的帮助类,额外提供了一层缓存给开发者,开发者可以自己具有缓存的需要进行设置;有mRecyclerPool,它是终极的缓存池,上述缓存都没有找到的情况下才会读取mRecyclerPool缓存;
缓存内容不同
ListView是对Item的最外层的View进行缓存。 RecyclerView是对ViewHolder进行缓存,ViewHolder是对Item的View的封装,ViewHolder在构造方法里面会通过findViewById将各个需要的View的引用设置好,是为了之后复用的时候不需要重新findViewById,提升效率。
缓存机制
ListView和RecyclerView的缓存机制大致类似:
如图7.15.1所示,在整个滑动的过程中,离开屏幕的Item立即被回收至缓存ScrapView,滑入屏幕的Item则会优先从缓存ScrapView中获取,只是ListView与RecyclerView的实现细节有差异。
ListView与RecyclerView缓存级别的对比
ListView(两级缓存):
| 是否需要回调createView | 是否需要回调bindView | 生命周期 | 备注 | |
|---|---|---|---|---|
| mActiveViews | 否 | 否 | onLayout函数周期内 | 用于屏幕itemView快速复用 |
| mScrapViews | 否 | 是 | 与mAdapter一致,当mAdatper被更换时,mScrapViews即被清除 |
ListView获取缓存的流程:
如图7.15.2所示,ListView会先通过position读取mActiveViews中的缓存,从这一级读取的缓存是可以快速复用,不需要重新绑定数据。如果mActiveViews中没有找到则会从下一级mScrapViews中读取,这一级读取的缓存是需要重新绑定数据。
RecyclerView(四级缓存):
| 是否需要回调createView | 是否需要调用bindView | 生命周期 | 备注 | |
|---|---|---|---|---|
| mAttachedScrap | 否 | 否 | onLayout函数周期中 | 用于屏幕内itemview快速复用 |
| mCacheViews | 否 | 否 | 与mAdapter一致,当mAdapter被更换时,mCacheViews即被缓存至mRecyclerPool | 默认上限为2,即缓存屏幕外2个itemView |
| mViewCacheExtension | 不直接使用,需要用户在定制,默认不实现 | |||
| mRecyclerPool | 否 | 是 | 与自身生命周期一致,不再被引用是即被释放 | 默认上限为5,技术上可以实现所有RecyclerViewPool共用同一个 |
RecyclerView获取缓存的流程,请阅读RecyclerView的回收复用原理一题,其中有关缓存流程的相关内容。
ListView和RecyclerView缓存机制基本一致:
1). listView 的mActiveViews和RecyclerView 的mAttachedScrap功能类似,设计的目的是快速复用屏幕上可见的列表项ItemView,而不需要重新createView和bindView;
2). listView的 mScrapView和RecyclerView 的mCachedViews + mReyclerViewPool功能类似,设计的目的是让即将进入屏幕的Item可以从缓存容器中读取缓存数据,减少耗时。
3). RecyclerView的优点在于两点内容:第一点mCacheViews的使用,可以实现屏幕外的列表项ItemView进入屏幕内时也不需要bindView,可以快速复用;第二点mRecyclerPool可以供多个RecyclerView共同使用;
客观来说,RecyclerView在特定场景下对ListView的缓存机制做了强加和完善。
详细关注公众号:Android老皮
还能解锁 《Android十大板块文档》 ,让学习更贴近未来实战。已形成PDF版
内容如下:
1.Android车载应用开发系统学习指南(附项目实战)
2.Android Framework学习指南,助力成为系统级开发高手
3.2023最新Android中高级面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习路线+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技术解析与实战,跨平台首要之选
7.Kotlin从入门到实战,全方面提升架构基础
8.高级Android插件化与组件化(含实战教程和源码)
9.Android 性能优化实战+360°全方面性能调优
10.Android零基础入门到精通,高手进阶之路