RecyclerView缓存机制

2020-03-20  本文已影响0人  allever

缓存层级(缓存结构/缓存类型)

这里的脏怎么理解呢?就是指那些在展示之前必须重新绑定的视图,比如一个视图原来展示的是“张三”,之后需要展示“李四”了,那么这个视图就是脏视图,需要重新绑定数据后再展示的。

这可以通过跳过初始布局或构造来显着提高性能

缓存变量

Recycler中的缓存变量

final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();
ArrayList<ViewHolder> mChangedScrap = null;
final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
private ViewCacheExtension mViewCacheExtension;
RecycledViewPool mRecyclerPool;

ChildHelper中的缓存变量

final List<View> mHiddenViews = new ArrayList<View>();

RecyclerView的复用流程

最终调用到Recycler的tryGetViewHolderForPositionByDeadline方法

//第一步
if (mState.isPreLayout()) {
    holder = getChangedScrapViewForPosition(position);
    fromScrapOrHiddenOrCache = holder != null;
}
//第二步
if (holder == null) {
    holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);
    //分三个流程
    1.从mAttachedScrap中查找
    2.ChildHelper类中的mHiddenViews中查找
    3.从mCachedViews中查找的
}
//第三步
if (holder == null && mViewCacheExtension != null) {
    final View view = mViewCacheExtension.getViewForPositionAndType(this, position, type);
    if (view != null) {
        holder = getChildViewHolder(view);
    }
}
//第四步
if (holder == null) {
    holder = getRecycledViewPool().getRecycledView(type);
}
//第五步
if (holder == null) {
    holder = mAdapter.createViewHolder(RecyclerView.this, type);
}
//最后
if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {
    ...
    final int offsetPosition = mAdapterHelper.findPositionOffset(position);
    bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs);
    //最终调用 mAdapter.bindViewHolder(holder, offsetPosition);
    ...
}
if (mState.isPreLayout()) {
    holder = getChangedScrapViewForPosition(position);
    fromScrapOrHiddenOrCache = holder != null;
}
if (holder == null) {
    holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);
}

ViewHolder getScrapOrHiddenOrCachedHolderForPosition(int position, boolean dryRun) {
    //1.从mAttachedScrap中查找
    for (int i = 0; i < scrapCount; i++) {
        final ViewHolder holder = mAttachedScrap.get(i);
        return holder;
    }
    //2.ChildHelper类中的mHiddenViews中查找
    if (!dryRun) {
        //最终调用 final View view = mHiddenViews.get(i);
        View view = mChildHelper.findHiddenNonRemovedView(position);
        if(view != null) {
            final ViewHolder vh = getChildViewHolderInt(view);
            return vh;
        }
    }
    //3.mCachedViews中查找
    final int cacheSize = mCachedViews.size();
    for (int i = 0; i < cacheSize; i++) {
        final ViewHolder holder = mCachedViews.get(i);
        return holder
    }
}
if (holder == null && mViewCacheExtension != null) {
    ...
    final View view = mViewCacheExtension.getViewForPositionAndType(this, position, type);
    if (view != null) {
        holder = getChildViewHolder(view);
    }
    ...
}
if (holder == null) {
    holder = getRecycledViewPool().getRecycledView(type);
}
if (holder == null) {
    holder = mAdapter.createViewHolder(RecyclerView.this, type);
}
if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {
    ...
    final int offsetPosition = mAdapterHelper.findPositionOffset(position);
    bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs);
    ...
}
private boolean tryBindViewHolderByDeadline(ViewHolder holder, int offsetPosition, int position, long deadlineNs) {
    ...
    mAdapter.bindViewHolder(holder, offsetPosition);
    ...
}

RecyclerView的回收流程

。。。

上一篇 下一篇

猜你喜欢

热点阅读