Android基础相关

RecyclerView的缓存机制

2021-01-09  本文已影响0人  来lol里

源码的追溯流程

onTouchEvent
Move
    scrollByInternal
        mLayout.scrollVerticallyBy(y, mRecycler, mState);
            LinearLayoutManager.scrollBy();
                 fill(recycler, mLayoutState, state, false);
                                    (while循环)layoutChunk();        
                                 layoutState.next(recycler);
                                 recycler.getViewForPosition(mCurrentPosition);
                                                tryGetViewHolderForPositionByDeadline//核心方法在这里
四级缓存
       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
上一篇下一篇

猜你喜欢

热点阅读