美文网首页
RecyclerView 缓存原理

RecyclerView 缓存原理

作者: yangLiHai | 来源:发表于2020-03-23 17:19 被阅读0次

    RecyclerView 缓存原理

    通常认为RecyclerView有四级缓存,RecyclerView的缓存是通过Recycler类来完成的,方法的入口:

    public View getViewForPosition(int position) {
        return getViewForPosition(position, false);
    }
    

    缓存的内容是ViewHolder,缓存的地方,是Recycler的几个list:

    final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<ViewHolder>();
    private ArrayList<ViewHolder> mChangedScrap = null;
    
    final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
    
    private final List<ViewHolder>
            mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);
    
    private int mViewCacheMax = DEFAULT_CACHE_SIZE;
    
    private RecycledViewPool mRecyclerPool;
    
    private ViewCacheExtension mViewCacheExtension;
    
    private static final int DEFAULT_CACHE_SIZE = 2;
    
    第一级缓存

    mAttachedScrap: 用于缓存显示在屏幕上的 item 的 ViewHolder
    mChangedScrap: 还是屏幕内的ViewHolder,没看懂啥意思,可能是用于缓存局部改变时候的holder

    第二级缓存

    mCachedViews:划出屏幕外的item,这个list的默认大小是2,

    第三级缓存

    mViewCacheExtension:自定义缓存,RecyclerView默认是没有实现的,留给开发者自己实现

    第四级缓存

    mRecyclerPool:mCachedViews的数量达到上限之后,会把ViewHolder存入mRecyclerPool。mRecyclerPool用SparseArray来缓存进入这一级的ViewHolder:

    static class ScrapData {
        final ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();
        int mMaxScrap = DEFAULT_MAX_SCRAP;
        long mCreateRunningAverageNs = 0;
        long mBindRunningAverageNs = 0;
    }
    SparseArray<ScrapData> mScrap = new SparseArray<>();
    

    但存在mRecyclerPool的 ViewHolder 的数据信息会被重置掉,相当于 ViewHolder 是一个重创新建的一样,所以需要重新调用 onBindViewHolder 来绑定数据,所以尽量不要让ViewHolder进入这一层

    缓存优化

    进入RecyclerPool的ViewHolder会被重置,会从新执行bindViewHolder,所以从效率上来讲,很费性能。

    所以为了避免进入这一层缓存,可以在在第三层自定义缓存自己实现,也就是自定义mViewCacheExtension。在这里自己维护一个viewType对应View的SparseArray。这样可以避免因为多种type导致的holder重建。

    public abstract static class ViewCacheExtension {
        @Nullable
        public abstract View getViewForPositionAndType(@NonNull Recycler recycler, int position,
                    int type);
        }
    

    注意getViewForPositionAndType返回的是view而不是ViewHolder,然后会通过view的layoutParams拿到ViewHolder。

    第二可以增大mCachedViews的缓存数量,改成你需要的量

    相关文章

      网友评论

          本文标题:RecyclerView 缓存原理

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