Recyclerview 复用之headview优化

版本:support-v7 25.3.1

发现问题

在对 性能优化-首页CPU占用优化 调研时发现,首页的OnCreateViewHolder存在高频次调用的情况,而常见的开源列表组件不存在此问题。

遂针对此问题,对recyclerview的复用机制进行分析。

缓存集合

1 mChangedScrap 表示数据已经改变的ViewHolder集合

image.png

2 mAttachedScrap 与RecyclerView尚未分离的ViewHolder集合

3 mCachedViews ViewHolder缓存集合,默认为2。

4 mViewCacheExtension 开发者可自定义集合

5 mRecyclerPool ViewHolder缓存池。 被用来做下一级的缓存。默认最大为五个。

image.png

缓存复用流程

从onCreateViewHolder的调用开始看

image.png

tryGetViewHolderForPositionByDeadline方法,也是复用机制的重点。

这是一个自带过期时间的view复用函数,返回的对象如果时间不允许,那么可能会是null或者未绑定的。

dryRun 控制使用完缓存之后,是否需要从缓存中删除。

image.png

1 从被改变的废料中获取组件

如果这里是一个改变了的废料,那么使用getChangedScrapViewForPosition函数去获取。

// 0) If there is a changed scrap, try to find from there

image.png

来看具体的实现方法,

ViewHolder getChangedScrapViewForPosition(int position)

image.png

2 根据 position 从已经改变的废料集合中搜索缓存

如果成功,则打回。 第二步 根据id查询废料缓存。

3 从隐藏或者缓存的组件集合中获取 根据posotion

getScrapOrHiddenOrCachedHolderForPosition // 1) Find by position from scrap/hidden list/cache

image.png

这里做了两件事情,第一个从缓存列表中获取holder,然后在验证其有效性。

其实这里的getScrapOrHiddenOrCachedHolderForPosition 方法是缓存的重点功能实现。

image.png

4 从隐藏和缓存组件集合中获取,根据ids

image.png

从自定义的扩展中读取缓存

略,项目中未使用此功能。

从RecyclerPool读取缓存

这级别的是一个根据view type 进行缓存的SparseArray对象。

image.png

收获

1) 加深了对RecyclerView 缓存机制的理解

2) 问题定位: 

项目中的headview的高度比itemview的高度,高出很多倍。 所以在 当head view被回收的时候,缓存中的itemview数量不足以复用,导致多次调用手动实例化方法。

3) 优化建议:

使用了headview的情况下,建议head view的高度不要比正常的item高度超过太多。 

这样可以使item的使用完全可以通过缓存消化,避免频繁的手动实例布局文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值