RecyclerView和ListView的缓存大战:别让列表卡成PPT

avatar
小常在创业IP属地:上海
02026-02-13:22:01:42字数 2001阅读 1

写过Android列表的,谁没被ListView的“视图错乱”坑过?我去年调了一个月的列表,最后发现根本不是数据问题——是缓存机制在作妖。今天不扯理论,就聊聊这两个控件的缓存到底咋回事,顺便说说为啥现在没人敢碰ListView了。


ListView:简单粗暴的“老黄牛”缓存

ListView的缓存机制就一句话:滑出屏幕的View,塞进一个叫RecycleBin的筐里,滑进来直接拿出来用
getView()里,你得自己写:

if (convertView == null) {
    convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
} else {
    // 直接复用!
}

问题在哪?

  • 筐太小:只缓存最近滑出的几个View,一滚快了,筐里没货,直接null重建,卡顿直接拉满。
  • 数据污染:比如你给Item设了TextView.setText("加载中"),滑出后没清空,复用时突然显示“加载中”——这坑我踩过三次,每次都要骂一句“这破ListView”。

RecyclerView:懒人福音的“智能缓存池”

RecyclerView不是升级版,是彻底重构。它把缓存玩成了“智能快递站”:

  1. 全局缓存池RecycledViewPool
    你建了5个RecyclerView?缓存池自动共享,不用每个列表自己造筐。
    (比如APP首页列表和详情页列表,能复用同一个图片加载的ViewHolder)
  2. 按需缓存ViewHolder绑定)
    onBindViewHolder()里直接绑定数据,不关心View怎么来的
    (再也不用在getView里写if (convertView == null)这种冗余代码了)
  3. 回收策略更狠
    滑出屏幕的View,先放“临时仓库”(ViewCacheExtension),不用立刻回收。
    (比如快速滑动时,仓库里的View能立刻顶上,不用等重建)

为什么RecyclerView能吊打ListView?

我拿真实项目对比过:

  • ListView:1000条数据,滚动时CPU飙到90%,偶尔闪屏。
  • RecyclerView:同样数据,滚动丝滑,CPU 30%左右,没见错乱过。

关键区别

机制ListViewRecyclerView
缓存范围单列表独立缓存全局缓存池+自定义扩展
视图复用逻辑你手动判断convertView系统自动复用ViewHolder
数据污染风险高(需手动清空)低(绑定时重置数据)
复杂场景支持网格/瀑布流要自己写LayoutManager直接支持

给新人的血泪建议

  1. 别碰ListView了,除非是Android 4.0以下的老项目。
  2. RecyclerView的缓存别乱调
    • 如果列表里有图片,RecyclerView默认会缓存图片,但别开setHasFixedSize(true)(会卡住)
    • setItemViewCacheSize(20)手动调缓存池大小,20够用,别塞太多(内存泄漏警告!)
  3. 重点onBindViewHolder必须重置View状态!
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.text.setText(data.get(position));
        // 别忘了!如果Item有图片,这里清空占位图
        holder.imageView.setImageResource(R.drawable.placeholder);
    }
    

最后一句大实话

ListView的缓存像老式缝纫机——能用,但卡顿得让你想砸屏幕。RecyclerView的缓存是智能洗衣机,甩干甩得飞起,还自带烘干。
别再为ListView的缓存问题熬夜了,升级RecyclerView,你的时间比代码值钱。

(写完这篇,我删了项目里最后1个ListView——真香。)

总资产 0
暂无其他文章

热门文章

暂无热门文章