英超联赛杯直播在线观看 Android架构师之深入理解RecyclerView复用懈弛存机制详解
发布日期:2021-09-10 14:18    点击次数:51

本文转载自微信公多号「Android开发编程」,作者Android开发编程。转载本文请有关Android开发编程公多号。

序言

学习源码,钻研源码编程思维,是程序开发者进阶的必经之路

  12月16日,体彩大乐透第20128期全国共开出3注1000万元基本投注一等奖。当期全国销量为2.74亿元,为国家筹集彩票公益金9898万元。

  12月的古城南京,气温早已跌破冰点,室外的人们蜷缩在厚厚的冬衣里,但是,在南京环宇城却是另一番景象,那里人潮涌动,那里欢笑不断,那里热情似火。为什么?自然是因为中国体育彩票吉祥物——乐小星,在这里聚光而来,闪亮登场啦!

  2020年12月17日下午,第六季“体彩爱行走”活动举行了捐赠仪式,江苏体彩现场将20万元“体彩爱心基金”捐赠给江苏省妇女儿童福利基金会,用于资助“我助妇儿康”项目。

  近日,湖北体彩武汉分中心组织20名优秀代销者代表,开展了以“微光熠熠 行走正能量”为主题的活动,学习抗疫精神,传递公益正能量。

  四川体彩在市场营销上始终采取推陈创新。对于线上“拉新”,四川体彩其实并不陌生。

行家都清新RecyclerView有回收复用机制,那么回收复用机制是如何作用的?

今天吾们就用源码来讲解英超联赛杯直播在线观看,一首学习

一、Recycler介绍

RecyclerView是经由过程内部类Recycler管理的缓存,那么Recycler中缓存的是什么?吾们清新RecyclerView在存在大量数据时照样能够滑动的如丝滑般通顺,而RecyclerView自己是一个ViewGroup,那么滑动时避免不了增补或移除子View(子View经由过程RecyclerView#Adapter中的onCreateViewHolder创建),倘若每次操纵子View都要去重新创建,一定会影响滑动的流 畅性,以是RecyclerView经由过程Recycler来缓存的是ViewHolder(内部包含子View),云云在滑动时能够复用子View,某些条件下还能够复用子View绑定的数据。以是内心上缓存是为了缩短重复绘制View和绑定数据的时间,从而挑高了滑动时的性能

public final class Recycler {         final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();         ArrayList<ViewHolder> mChangedScrap = null;         final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();         private final List<ViewHolder>                 mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);         private int mRequestedCacheMax = DEFAULT_CACHE_SIZE;         int mViewCacheMax = DEFAULT_CACHE_SIZE;         RecycledViewPool mRecyclerPool;         private ViewCacheExtension mViewCacheExtension;         static final int DEFAULT_CACHE_SIZE = 2; 

Recycler缓存ViewHolder对象有4个等级,优先级从高到底挨次为:

1、ArrayList mAttachedScrap --- 缓存屏幕中可见周围的ViewHolder

2、ArrayList mCachedViews ---- 缓存滑动时即将与RecyclerView别离的ViewHolder,按子View的position或id缓存,默认最多存放2个

3、ViewCacheExtension mViewCacheExtension --- 开发者自走实现的缓存

4、RecycledViewPool mRecyclerPool --- ViewHolder缓存池,内心上是一个SparseArray,其中key是ViewType(int类型),value存放的是 ArrayList< ViewHolder>,默认每个ArrayList中最多存放5个ViewHolder。

二、缓存机制分析详解

RecyclerView滑动时会触发onTouchEvent#onMove,回收及复用ViewHolder在这边就会最先。吾们清新竖立RecyclerView时必要竖立LayoutManager,LayoutManager负责RecyclerView的组织,包含对ItemView的获取与复用。以LinearLayoutManager为例,当RecyclerView重新组织时会挨次实走下面几个手段:

onLayoutChildren():对RecyclerView进走组织的入口手段

fill(): 负责对盈余空间赓续地填充,调用的手段是layoutChunk()

layoutChunk():负责填充View,该View最后是经由过程在缓存类Recycler中找到正当的View的

上述的整个调用链:onLayoutChildren()->fill()->layoutChunk()->next()->getViewForPosition(),getViewForPosition()即是是从RecyclerView的回收机制实现类Recycler中获取正当的View,

下面主要就来从望这个Recycler#getViewForPosition()的实现。

@NonNull public View getViewForPosition(int position) {     return getViewForPosition(position, false); } View getViewForPosition(int position, boolean dryRun) {     return tryGetViewHolderForPositionByDeadline(position, dryRun, FOREVER_NS).itemView; } 

他们都会实走tryGetViewHolderForPositionByDeadline函数,赓续跟进去:

//按照传入的position获取ViewHolder

ViewHolder tryGetViewHolderForPositionByDeadline(int position,         boolean dryRun, long deadlineNs) {     ...省略         boolean fromScrapOrHiddenOrCache = false;     ViewHolder holder = null;     //预组织 属于稀奇情况 从mChangedScrap中获取ViewHolder     if (mState.isPreLayout()) {         holder = getChangedScrapViewForPosition(position);         fromScrapOrHiddenOrCache = holder != null;     }     if (holder == null) {         //1、尝试从mAttachedScrap中获取ViewHolder,此时获取的是屏幕中可见周围中的ViewHolder         //2、mAttachedScrap缓存中异国的话,赓续从mCachedViews尝试获取ViewHolder         holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);      ...省略     }     if (holder == null) {         final int offsetPosition = mAdapterHelper.findPositionOffset(position);         ...省略         final int type = mAdapter.getItemViewType(offsetPosition);         //倘若Adapter中声清新Id,尝试从id中获取,这边不属于缓存         if (mAdapter.hasStableIds()) {             holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),                     type, dryRun);         }         if (holder == null && mViewCacheExtension != null) {             3、从自定义缓存mViewCacheExtension中尝试获取ViewHolder,该缓存必要开发者实现             final View view = mViewCacheExtension                     .getViewForPositionAndType(this, position, type);             if (view != null) {                 holder = getChildViewHolder(view);             }         }         if (holder == null) { // fallback to pool             //4、从缓存池mRecyclerPool中尝试获取ViewHolder             holder = getRecycledViewPool().getRecycledView(type);             if (holder != null) {                 //倘若获取成功,会重置ViewHolder状态,以是必要重新实走Adapter#onBindViewHolder绑定数据                 holder.resetInternal();                 if (FORCE_INVALIDATE_DISPLAY_LIST) {                     invalidateDisplayListInt(holder);                 }             }         }         if (holder == null) {             ...省略           //5、若以上缓存中都异国找到对答的ViewHolder,最后会调用Adapter中的onCreateViewHolder创建一个             holder = mAdapter.createViewHolder(RecyclerView.this, type);         }     }     boolean bound = false;     if (mState.isPreLayout() && holder.isBound()) {         holder.mPreLayoutPosition = position;     } else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {         final int offsetPosition = mAdapterHelper.findPositionOffset(position);         //6、倘若必要绑定数据,会调用Adapter#onBindViewHolder来绑定数据         bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs);     }     ...省略     return holder; } 

经由过程mAttachedScrap、mCachedViews及mViewCacheExtension获取的ViewHolder不必要重新创建组织及绑定数据;经由过程缓存池mRecyclerPool获取的ViewHolder不必要重新创建组织,但是必要重新绑定数据;倘若上述缓存中都异国获取到现在的ViewHolder,那么就会回调Adapter#onCreateViewHolder创建组织,以及回调Adapter#onBindViewHolder来绑定数据

总结

RecyclerView 滑动场景下的回收复用涉及到的组织体两个:

mCachedViews 和 RecyclerViewPool mCachedViews 优先级高于 RecyclerViewPool,回收时,最新的 ViewHolder 都是去 mCachedViews 里放,倘若它满了,那就移出一个扔到 ViewPool 里益空出位置来缓存最新的 ViewHolder。 复用时,也是先到 mCachedViews 里找 ViewHolder,但必要各栽匹配条件,概括一下就是只有正本位置的卡位能够复用存在 mCachedViews 里的 ViewHolder,倘若 mCachedViews 里异国,那么才去 ViewPool 里找。 在 ViewPool 里的 ViewHolder 都是跟崭新的 ViewHolder 相通,只要 type 相通,有找到,就能够拿出来复用,重新绑定下数据即可。

【编辑选举】英超联赛杯直播在线观看

存储器市场超预期转跌 半导体缺货潮终结了吗 Linux 编辑器之神 vim 的 IO 存储原理 Longhorn,Kubernetes 云原生分布式块存储 SQL Server 查询存储,做查询优化的利器 Longhorn 云原生分布式块存储解决方案设计架议和概念