RecyclerView源码太复杂了, 这里目前想只记住结论哈.
RecyclerView中ViewHolder或者View的缓存是通过Recycler实现的.
public final class Recycler {
// 一级缓存
final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();
ArrayList<ViewHolder> mChangedScrap = null;
// 二级缓存
final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
private int mRequestedCacheMax = DEFAULT_CACHE_SIZE;
int mViewCacheMax = DEFAULT_CACHE_SIZE;
// 四级缓存
RecycledViewPool mRecyclerPool;
// 三级缓存
private ViewCacheExtension mViewCacheExtension;
static final int DEFAULT_CACHE_SIZE = 2;
}
![](https://img.haomeiwen.com/i1884421/51d4237d4d93bcfa.png)
![](https://img.haomeiwen.com/i1884421/908be50f005cc58a.png)
上面这个流程图与下面的代码有关
@Nullable
ViewHolder tryGetViewHolderForPositionByDeadline(int position, boolean dryRun, long deadlineNs) {
boolean fromScrapOrHiddenOrCache = false;
ViewHolder holder = null;
// 0) If there is a changed scrap, try to find from there
if (mState.isPreLayout()) {
holder = getChangedScrapViewForPosition(position);
fromScrapOrHiddenOrCache = holder != null;
}
// 1) Find by position from scrap/hidden list/cache
if (holder == null) {
holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);
if (holder != null) {
...
}
}
if (holder == null) {
final int offsetPosition = mAdapterHelper.findPositionOffset(position);
final int type = mAdapter.getItemViewType(offsetPosition);
// 2) Find from scrap/cache via stable ids, if exists
if (mAdapter.hasStableIds()) {
// 从mCachedViews中获取缓存的ViewHolder
holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),
type, dryRun);
if (holder != null) {
// update position
holder.mPosition = offsetPosition;
fromScrapOrHiddenOrCache = true;
}
}
if (holder == null) { // fallback to pool
// 根据Type从RecyclerPool中获取ViewHolder
holder = getRecycledViewPool().getRecycledView(type);
if (holder != null) {
// 获取ViewHolder之后, 调用这里将ViewHolder中的状态进行重置;
holder.resetInternal();
}
}
if (holder == null) {
// 如果没有找到缓存的ViewHolder, 则新建ViewHolder, 新建ViewHolder时会设置对应的type
holder = mAdapter.createViewHolder(RecyclerView.this, type);
}
}
boolean bound = false;
if (mState.isPreLayout() && holder.isBound()) {
// do not update unless we absolutely have to.
holder.mPreLayoutPosition = position;
// 新建ViewHolder或者ViewHolder.resetInternal之后, mFlags被置为0, 然后进入if语句
// 通过tryBindViewHolderByDeadline最终触发onBindViewHolder()的执行.
} else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {
final int offsetPosition = mAdapterHelper.findPositionOffset(position);
// 这里最终会触发Adapter.onBindViewHolder的执行
bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs);
}
return holder;
}
ViewHolder.resetInternal
void resetInternal() {
mFlags = 0;
}
boolean isInvalid() {
return (mFlags & FLAG_INVALID) != 0;
}
boolean needsUpdate() {
return (mFlags & FLAG_UPDATE) != 0;
}
boolean isBound() {
return (mFlags & FLAG_BOUND) != 0;
}
参考文章:
https://zhuanlan.zhihu.com/p/23339185
https://www.jianshu.com/p/e44961f8add5
网友评论