美文网首页Android基础相关
RecyclerView的缓存机制

RecyclerView的缓存机制

作者: 来lol里 | 来源:发表于2021-01-09 12:43 被阅读0次

源码的追溯流程

onTouchEvent
Move
    scrollByInternal
        mLayout.scrollVerticallyBy(y, mRecycler, mState);
            LinearLayoutManager.scrollBy();
                 fill(recycler, mLayoutState, state, false);
                                    (while循环)layoutChunk();        
                                 layoutState.next(recycler);
                                 recycler.getViewForPosition(mCurrentPosition);
                                                tryGetViewHolderForPositionByDeadline//核心方法在这里
四级缓存
  • mAttachedScrap和mChangedScrap
    mAttachedScrap 缓存的是从屏幕上分离出来的ViewHolder,但是又即将添加到屏幕上去的ViewHolder。比如说,RecyclerView上下滑动,滑出一个新的Item,此时会重新调用LayoutManager的onLayoutChildren方法,从而会将屏幕上所有的ViewHolder先scrap掉(含义就是废弃掉),添加到mAttachedScrap里面去,然后在重新布局每个ItemView时,会从优先mAttachedScrap里面获取,这样效率就会非常的高。这个过程不会重新onBindViewHolder。
    mChangedScrap 这个缓存和上边的mAttachedScrap是一样的,唯一不同的从名字也可以看出来,它存放的是发生了变化的ViewHolder,如果使用到了这里的缓存的ViewHolder是要重新走Adapter的绑定方法onBindViewHolder的。这个和上个保存的都是dettach掉的ViewHolder。
    具体方法在
       void scrapView(View view) {
            final ViewHolder holder = getChildViewHolderInt(view);
            if (holder.hasAnyOfTheFlags(ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_INVALID)
                    || !holder.isUpdated() || canReuseUpdatedViewHolder(holder)) {
                if (holder.isInvalid() && !holder.isRemoved() && !mAdapter.hasStableIds()) {
                    throw new IllegalArgumentException("Called scrap view with an invalid view."
                            + " Invalid views cannot be reused from scrap, they should rebound from"
                            + " recycler pool." + exceptionLabel());
                }
                holder.setScrapContainer(this, false);
                mAttachedScrap.add(holder);
            } else {
                if (mChangedScrap == null) {
                    mChangedScrap = new ArrayList<ViewHolder>();
                }
                holder.setScrapContainer(this, true);
                mChangedScrap.add(holder);
            }
        }

mCachedViews 默认大小为2,通常用来存储预取的ViewHolder,同时在回收ViewHolder时,也会可能存储一部分的ViewHolder,这部分的ViewHolder通常来说,意义跟一级缓存差不多。这个变量同样是一个存放ViewHolder对象的ArrayList,但是这个不同于上面的两个里面存放的是dettach掉的视图,它里面存放的是已经remove掉的视图,已经和RV分离的关系的视图,但是它里面的ViewHolder依然保存着之前的信息,比如position、和绑定的数据等等。这一级缓存是有容量限制的,默认是2。先进先出,当超过两个了,前一个被放入RecyclerViewPool中,后边的add进来。
ViewCacheExtension 自定义缓存用到较少
RecyclerViewPool 默认大小为5,这里面保存的ViewHolder不仅仅是removed掉的视图,而且是恢复了出厂设置的视图,任何绑定过的痕迹都没有了,想用这里缓存的ViewHolder是一定要走onBindViewHolder 的绑定方法的。而且我们知道RV支持多布局,所以这里的缓存是按照itemType来分开存储的,即每种itemType最多缓存5个。


image.png

相关文章

网友评论

    本文标题:RecyclerView的缓存机制

    本文链接:https://www.haomeiwen.com/subject/xcccaktx.html