精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Android架構(gòu)師之深入理解RecyclerView復(fù)用和緩存機(jī)制詳解

移動(dòng)開(kāi)發(fā) Android
RecyclerView滑動(dòng)時(shí)會(huì)觸發(fā)onTouchEvent#onMove,回收及復(fù)用ViewHolder在這里就會(huì)開(kāi)始。我們知道設(shè)置RecyclerView時(shí)需要設(shè)置LayoutManager,LayoutManager負(fù)責(zé)RecyclerView的布局,包含對(duì)ItemView的獲取與復(fù)用。

本文轉(zhuǎn)載自微信公眾號(hào)「Android開(kāi)發(fā)編程」,作者Android開(kāi)發(fā)編程。轉(zhuǎn)載本文請(qǐng)聯(lián)系A(chǔ)ndroid開(kāi)發(fā)編程公眾號(hào)。

前言

學(xué)習(xí)源碼,研究源碼編程思想,是程序開(kāi)發(fā)者進(jìn)階的必經(jīng)之路

大家都知道RecyclerView有回收復(fù)用機(jī)制,那么回收復(fù)用機(jī)制是如何作用的?

今天我們就用源碼來(lái)講解,一起學(xué)習(xí)

一、Recycler介紹

RecyclerView是通過(guò)內(nèi)部類Recycler管理的緩存,那么Recycler中緩存的是什么?我們知道RecyclerView在存在大量數(shù)據(jù)時(shí)依然可以滑動(dòng)的如絲滑般順暢,而RecyclerView本身是一個(gè)ViewGroup,那么滑動(dòng)時(shí)避免不了添加或移除子View(子View通過(guò)RecyclerView#Adapter中的onCreateViewHolder創(chuàng)建),如果每次使用子View都要去重新創(chuàng)建,肯定會(huì)影響滑動(dòng)的流 暢性,所以RecyclerView通過(guò)Recycler來(lái)緩存的是ViewHolder(內(nèi)部包含子View),這樣在滑動(dòng)時(shí)可以復(fù)用子View,某些條件下還可以復(fù)用子View綁定的數(shù)據(jù)。所以本質(zhì)上緩存是為了減少重復(fù)繪制View和綁定數(shù)據(jù)的時(shí)間,從而提高了滑動(dòng)時(shí)的性能

  1. public final class Recycler { 
  2.         final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>(); 
  3.         ArrayList<ViewHolder> mChangedScrap = null
  4.         final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>(); 
  5.         private final List<ViewHolder> 
  6.                 mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap); 
  7.         private int mRequestedCacheMax = DEFAULT_CACHE_SIZE; 
  8.         int mViewCacheMax = DEFAULT_CACHE_SIZE; 
  9.         RecycledViewPool mRecyclerPool; 
  10.         private ViewCacheExtension mViewCacheExtension; 
  11.         static final int DEFAULT_CACHE_SIZE = 2; 

Recycler緩存ViewHolder對(duì)象有4個(gè)等級(jí),優(yōu)先級(jí)從高到底依次為:

1、ArrayList mAttachedScrap --- 緩存屏幕中可見(jiàn)范圍的ViewHolder

2、ArrayList mCachedViews ---- 緩存滑動(dòng)時(shí)即將與RecyclerView分離的ViewHolder,按子View的position或id緩存,默認(rèn)最多存放2個(gè)

3、ViewCacheExtension mViewCacheExtension --- 開(kāi)發(fā)者自行實(shí)現(xiàn)的緩存

4、RecycledViewPool mRecyclerPool --- ViewHolder緩存池,本質(zhì)上是一個(gè)SparseArray,其中key是ViewType(int類型),value存放的是 ArrayList< ViewHolder>,默認(rèn)每個(gè)ArrayList中最多存放5個(gè)ViewHolder。

二、緩存機(jī)制分析詳解

RecyclerView滑動(dòng)時(shí)會(huì)觸發(fā)onTouchEvent#onMove,回收及復(fù)用ViewHolder在這里就會(huì)開(kāi)始。我們知道設(shè)置RecyclerView時(shí)需要設(shè)置LayoutManager,LayoutManager負(fù)責(zé)RecyclerView的布局,包含對(duì)ItemView的獲取與復(fù)用。以LinearLayoutManager為例,當(dāng)RecyclerView重新布局時(shí)會(huì)依次執(zhí)行下面幾個(gè)方法:

onLayoutChildren():對(duì)RecyclerView進(jìn)行布局的入口方法

fill(): 負(fù)責(zé)對(duì)剩余空間不斷地填充,調(diào)用的方法是layoutChunk()

layoutChunk():負(fù)責(zé)填充View,該View最終是通過(guò)在緩存類Recycler中找到合適的View的

上述的整個(gè)調(diào)用鏈:onLayoutChildren()->fill()->layoutChunk()->next()->getViewForPosition(),getViewForPosition()即是是從RecyclerView的回收機(jī)制實(shí)現(xiàn)類Recycler中獲取合適的View,

下面主要就來(lái)從看這個(gè)Recycler#getViewForPosition()的實(shí)現(xiàn)。

  1. @NonNull 
  2. public View getViewForPosition(int position) { 
  3.     return getViewForPosition(position, false); 
  4. View getViewForPosition(int position, boolean dryRun) { 
  5.     return tryGetViewHolderForPositionByDeadline(position, dryRun, FOREVER_NS).itemView; 

他們都會(huì)執(zhí)行tryGetViewHolderForPositionByDeadline函數(shù),繼續(xù)跟進(jìn)去:

//根據(jù)傳入的position獲取ViewHolder

  1. ViewHolder tryGetViewHolderForPositionByDeadline(int position, 
  2.         boolean dryRun, long deadlineNs) { 
  3.     ...省略     
  4.     boolean fromScrapOrHiddenOrCache = false
  5.     ViewHolder holder = null
  6.     //預(yù)布局 屬于特殊情況 從mChangedScrap中獲取ViewHolder 
  7.     if (mState.isPreLayout()) { 
  8.         holder = getChangedScrapViewForPosition(position); 
  9.         fromScrapOrHiddenOrCache = holder != null
  10.     } 
  11.     if (holder == null) { 
  12.         //1、嘗試從mAttachedScrap中獲取ViewHolder,此時(shí)獲取的是屏幕中可見(jiàn)范圍中的ViewHolder 
  13.         //2、mAttachedScrap緩存中沒(méi)有的話,繼續(xù)從mCachedViews嘗試獲取ViewHolder 
  14.         holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun); 
  15.      ...省略 
  16.     } 
  17.     if (holder == null) { 
  18.         final int offsetPosition = mAdapterHelper.findPositionOffset(position); 
  19.         ...省略 
  20.         final int type = mAdapter.getItemViewType(offsetPosition); 
  21.         //如果Adapter中聲明了Id,嘗試從id中獲取,這里不屬于緩存 
  22.         if (mAdapter.hasStableIds()) { 
  23.             holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition), 
  24.                     type, dryRun); 
  25.         } 
  26.         if (holder == null && mViewCacheExtension != null) { 
  27.             3、從自定義緩存mViewCacheExtension中嘗試獲取ViewHolder,該緩存需要開(kāi)發(fā)者實(shí)現(xiàn) 
  28.             final View view = mViewCacheExtension 
  29.                     .getViewForPositionAndType(this, position, type); 
  30.             if (view != null) { 
  31.                 holder = getChildViewHolder(view); 
  32.             } 
  33.         } 
  34.         if (holder == null) { // fallback to pool 
  35.             //4、從緩存池mRecyclerPool中嘗試獲取ViewHolder 
  36.             holder = getRecycledViewPool().getRecycledView(type); 
  37.             if (holder != null) { 
  38.                 //如果獲取成功,會(huì)重置ViewHolder狀態(tài),所以需要重新執(zhí)行Adapter#onBindViewHolder綁定數(shù)據(jù) 
  39.                 holder.resetInternal(); 
  40.                 if (FORCE_INVALIDATE_DISPLAY_LIST) { 
  41.                     invalidateDisplayListInt(holder); 
  42.                 } 
  43.             } 
  44.         } 
  45.         if (holder == null) { 
  46.             ...省略 
  47.           //5、若以上緩存中都沒(méi)有找到對(duì)應(yīng)的ViewHolder,最終會(huì)調(diào)用Adapter中的onCreateViewHolder創(chuàng)建一個(gè) 
  48.             holder = mAdapter.createViewHolder(RecyclerView.this, type); 
  49.         } 
  50.     } 
  51.     boolean bound = false
  52.     if (mState.isPreLayout() && holder.isBound()) { 
  53.         holder.mPreLayoutPosition = position; 
  54.     } else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) { 
  55.         final int offsetPosition = mAdapterHelper.findPositionOffset(position); 
  56.         //6、如果需要綁定數(shù)據(jù),會(huì)調(diào)用Adapter#onBindViewHolder來(lái)綁定數(shù)據(jù) 
  57.         bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs); 
  58.     } 
  59.     ...省略 
  60.     return holder; 

通過(guò)mAttachedScrap、mCachedViews及mViewCacheExtension獲取的ViewHolder不需要重新創(chuàng)建布局及綁定數(shù)據(jù);通過(guò)緩存池mRecyclerPool獲取的ViewHolder不需要重新創(chuàng)建布局,但是需要重新綁定數(shù)據(jù);如果上述緩存中都沒(méi)有獲取到目標(biāo)ViewHolder,那么就會(huì)回調(diào)Adapter#onCreateViewHolder創(chuàng)建布局,以及回調(diào)Adapter#onBindViewHolder來(lái)綁定數(shù)據(jù)

總結(jié)

RecyclerView 滑動(dòng)場(chǎng)景下的回收復(fù)用涉及到的結(jié)構(gòu)體兩個(gè):

 

  • mCachedViews 和 RecyclerViewPool
  • mCachedViews 優(yōu)先級(jí)高于 RecyclerViewPool,回收時(shí),最新的 ViewHolder 都是往 mCachedViews 里放,如果它滿了,那就移出一個(gè)扔到 ViewPool 里好空出位置來(lái)緩存最新的 ViewHolder。
  • 復(fù)用時(shí),也是先到 mCachedViews 里找 ViewHolder,但需要各種匹配條件,概括一下就是只有原來(lái)位置的卡位可以復(fù)用存在 mCachedViews 里的 ViewHolder,如果 mCachedViews 里沒(méi)有,那么才去 ViewPool 里找。
  • 在 ViewPool 里的 ViewHolder 都是跟全新的 ViewHolder 一樣,只要 type 一樣,有找到,就可以拿出來(lái)復(fù)用,重新綁定下數(shù)據(jù)即可。

 

責(zé)任編輯:武曉燕 來(lái)源: Android開(kāi)發(fā)編程
相關(guān)推薦

2019-10-18 08:22:43

BIONIOAIO

2021-09-18 06:56:01

JavaCAS機(jī)制

2017-05-03 17:00:16

Android渲染機(jī)制

2021-07-22 09:55:28

瀏覽器前端緩存

2021-10-15 09:19:17

AndroidSharedPrefe分析源碼

2021-09-10 07:31:54

AndroidAppStartup原理

2019-03-18 09:50:44

Nginx架構(gòu)服務(wù)器

2018-12-27 12:34:42

HadoopHDFS分布式系統(tǒng)

2017-01-13 22:42:15

iosswift

2021-02-17 11:25:33

前端JavaScriptthis

2021-09-16 06:44:04

Android進(jìn)階流程

2017-08-15 13:05:58

Serverless架構(gòu)開(kāi)發(fā)運(yùn)維

2017-07-12 14:58:21

AndroidInstant Run

2021-09-15 07:31:33

Android窗口管理

2017-11-14 14:41:11

Java泛型IO

2021-09-24 08:10:40

Java 語(yǔ)言 Java 基礎(chǔ)

2023-10-13 13:30:00

MySQL鎖機(jī)制

2021-09-30 07:36:51

AndroidViewDraw

2023-06-07 15:34:21

架構(gòu)層次結(jié)構(gòu)

2024-11-11 17:12:22

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

99热精品在线播放| 天堂在线中文视频| 999av小视频在线| 三级欧美日韩| 亚洲图片自拍偷拍| 久久99精品久久久久子伦| 亚洲乱码国产乱码精品| 色喇叭免费久久综合网| 日韩精品一区二区三区三区免费 | 国产videos久久| 精品视频一区 二区 三区| 好色先生视频污| 亚洲av片在线观看| 欧美一区高清| 欧美网站一区二区| 成人在线免费高清视频| 天堂在线中文| 老司机免费视频一区二区三区| 蜜月aⅴ免费一区二区三区| 亚洲天堂美女视频| 欧美激情免费| 日韩高清不卡在线| 操人视频在线观看欧美| 亚洲黄色在线网站| 欧美经典一区| 欧美专区日韩专区| 欧美一区二区福利| 国产精品久久影视| 亚洲在线网站| 久热爱精品视频线路一| 超碰97人人干| 草草视频在线一区二区| 欧美系列在线观看| 男人揉女人奶房视频60分| av在线麻豆| 国产精选一区二区三区| 国产成人精品免费久久久久| 精品午夜福利在线观看| 久久麻豆精品| 亚洲午夜小视频| 亚洲国产精品自拍视频| 日韩一区二区三区精品 | 国产一区二区三区乱码| 香蕉视频在线免费看| 久久影院午夜片一区| 91香蕉嫩草影院入口| 中文字幕在线观看高清| 视频一区视频二区在线观看| 97超级碰碰碰久久久| 久久婷婷一区二区| 亚洲大全视频| 久久韩剧网电视剧| 国产美女网站视频| 精品无人区麻豆乱码久久久| 亚洲欧美国产精品久久久久久久| 欧美a在线视频| free性护士videos欧美| 一区二区三区精密机械公司| 香蕉精品视频在线| 国内精品久久久久久久久久| 理论片日本一区| 国产一区二中文字幕在线看 | 欧美美女视频在线观看| 亚洲天堂2018av| 草民电影神马电影一区二区| 在线观看91精品国产入口| 那种视频在线观看| 最新欧美电影| 欧美伊人久久久久久久久影院| 北条麻妃在线一区| 欧美成人资源| 亚洲欧美激情在线| 91香蕉视频网址| 天天摸夜夜添狠狠添婷婷| av在线播放不卡| 精品一区二区久久久久久久网站| 手机看片福利在线| 91捆绑美女网站| 欧美一区2区三区4区公司二百| 国产黄在线播放| 国产精品传媒视频| 国外成人在线视频网站| 日韩在线观看视频一区二区三区| av午夜一区麻豆| 免费中文日韩| 日韩美女网站| 亚洲精品v日韩精品| 欧美狂野激情性xxxx在线观| 乱馆动漫1~6集在线观看| 日韩欧美aaa| 亚洲精品20p| 一区二区三区视频播放| 亚洲精品国产品国语在线| 成人无码av片在线观看| 亚洲午夜精品一区 二区 三区| 久久99精品视频一区97| 可以免费在线观看的av| 欧美a一区二区| 91久久国产综合久久蜜月精品| 午夜国产在线观看| 国产欧美一区视频| 久久久久久国产精品一区| 国产永久免费高清在线观看视频| 国产精品拍天天在线| 国产一区 在线播放| 都市激情亚洲一区| 91精品综合久久久久久| 在线观看av中文字幕| 欧美独立站高清久久| 久久久久久伊人| 中文字幕在线播放不卡| 成人短视频下载| 亚洲制服中文| 久久精品美女| 国产午夜精品无码| 国产精品久久久久久久久妇女| 久久99精品国产99久久6尤物| 天堂中文字幕在线观看| 国产毛片精品视频| 日韩福利二区| 免费在线观看的电影网站| 色综合天天综合网天天狠天天| 天堂av手机在线| 精品国产乱码久久久久久1区2匹| 欧美精品videosex牲欧美| 中日韩在线观看视频| 99re视频精品| 黄色片免费在线观看视频| av成人在线看| 国产视频久久久久久久| 久久这里只有精品免费| 久久精品国产精品亚洲精品 | 日韩av网址大全| 欧美精品在线观看| 一级欧美一级日韩| 久久综合网色—综合色88| 成人在线视频一区二区三区| 欧美在线se| 中文字幕久精品免费视频| 伊人手机在线视频| 成人avav影音| 久久精品无码中文字幕| 日韩精品免费视频一区二区三区 | 成人永久免费| 菠萝蜜视频国产在线播放| 欧美日韩在线免费视频| 亚洲一区视频在线播放| 久久久久久黄| 精品999在线观看| 成人免费高清观看| 日韩一区二区在线观看视频播放| 中文字幕求饶的少妇| 奇米一区二区三区| 亚洲精品第一区二区三区| 欧美va在线观看| 揄拍成人国产精品视频| 国产日韩在线免费观看| 国产亚洲成年网址在线观看| 成人小视频在线看| 色综合中文网| 国产精品成人免费电影| 国产1区2区3区在线| 在线视频欧美区| 国内精品卡一卡二卡三| 日本不卡123| 亚洲自拍的二区三区| 国产69精品久久久久9999人| 色偷偷91综合久久噜噜| 国产手机av在线| 亚洲在线观看免费| 国产精品久久久久久亚洲色| 亚洲精品女人| 国产精品久久久久秋霞鲁丝| 国产午夜在线观看| 精品视频色一区| 中文字幕av播放| 国产99久久久国产精品免费看| 日本福利视频一区| 91福利精品在线观看| 中文字幕亚洲综合久久筱田步美| 国产一区二区三区黄片| 亚洲老妇xxxxxx| 北京富婆泄欲对白| 久久久久99| 一区一区视频| 91大神精品| 欧洲美女7788成人免费视频| 国产在线资源| 91精品在线免费| 日本在线观看中文字幕| 国产一区二区三区美女| 丁香六月激情婷婷| 国产99亚洲| 亚洲淫片在线视频| 秋霞伦理一区| 色偷偷亚洲男人天堂| 精品久久久久中文慕人妻| 狠狠躁夜夜躁人人爽天天天天97| 国产一区二区三区精品在线| 国产很黄免费观看久久| 欧美s码亚洲码精品m码| 欧美超碰在线| 精品一区二区不卡| 国产精品视频一区二区三区| 777午夜精品福利在线观看| 日本www在线| 亚洲国产另类av| 国产精品一区二区三区久久久| 欧美日韩在线中文字幕| 一区二区在线免费| 久久国产精品无码一级毛片| 韩国欧美国产一区| 亚洲日本理论电影| 99re热精品视频| 国产91精品青草社区| 俄罗斯嫩小性bbwbbw| 在线观看日韩高清av| 久久国产精品波多野结衣| 国产精品系列在线播放| 久久久免费视频网站| 综合亚洲视频| 日韩精品av一区二区三区| 亚洲精品一二三**| 国产伦精品一区二区三区精品视频| 91福利在线尤物| 久久精品久久久久| 国产区在线视频| 精品国产乱码久久久久久图片| 中文字幕一区二区三区人妻四季| 亚洲午夜av在线| 三上悠亚作品在线观看| 国产亚洲va综合人人澡精品 | 一区二区不卡视频| 窝窝社区一区二区| 国产乱码精品一区二区三区不卡| 精品女同一区二区三区在线观看| 欧美一级片久久久久久久| 久久大胆人体| 欧美大片免费观看| 免费**毛片在线| 伊人精品在线观看| 欧美大片aaa| 日韩电影免费在线观看中文字幕| 99久久久久久久| 9191精品国产综合久久久久久| 久久久久久久久久一级| 色中色一区二区| av大片在线免费观看| 午夜精品aaa| 久久精品免费av| 亚洲一区二区三区免费视频| 老湿机69福利| 亚洲精品高清在线| 久久久美女视频| 一区二区三区国产| 欧美成欧美va| 亚洲一线二线三线视频| 国产av无码专区亚洲av毛网站| 亚洲免费av网站| 久久黄色小视频| 亚洲成a人v欧美综合天堂下载 | 国产精品手机播放| av在线播放一区| 国产精品欧美风情| 欧美成人免费全部网站| 成人黄色激情网| 久久99成人| 国产高清在线一区二区| 国产精东传媒成人av电影| 国产一区二区三区奇米久涩| 日本午夜精品久久久| 免费h精品视频在线播放| 久久99青青| 一区二区91美女张开腿让人桶| 国产一区二区三区四区五区| 亚洲精品不卡| 欧美视频二区| 国产日产欧美视频| 日本欧美加勒比视频| 日韩av一卡二卡三卡| 国产精品一卡二卡| 亚洲激情 欧美| 国产欧美一区二区精品秋霞影院| 69精品无码成人久久久久久| 中文字幕亚洲综合久久菠萝蜜| 欧美日韩成人免费观看| 精品成人av一区| 瑟瑟视频在线免费观看| 欧美一区国产二区| 西西人体44www大胆无码| 国产亚洲精品久久久久久| 成人av福利| 97色在线播放视频| 成人在线视频免费看| 9a蜜桃久久久久久免费| 欧美精品momsxxx| 尤物一区二区三区| 影音国产精品| 亚洲黄色小视频在线观看| 国产91丝袜在线18| 国产在线观看h| 一区二区三区中文免费| 91精品一区二区三区四区| 色哟哟在线观看| 在线观看国产成人av片| 婷婷av在线| 国产精品久久久久久久一区探花| 视频一区国产| 日韩av电影免费观看| 狠狠综合久久| 一区二区在线观看网站| 亚洲午夜一级| 国产成人黄色网址| av不卡在线播放| 欧美日韩午夜视频| 色88888久久久久久影院野外| 国产av一区二区三区| 亚洲女在线观看| 国产美女一区视频| 国产专区欧美专区| 九九视频精品全部免费播放| 狠狠精品干练久久久无码中文字幕 | 新67194成人永久网站| 天天综合成人网| 欧美极品另类videosde| 日韩经典在线观看| 欧美一区二区三区白人| 成人在线视频成人| 欧美亚洲成人网| jizz国产精品| 在线视频一二三区| 久久国产精品免费| 中文字幕免费高清| 精品久久久久久国产91| 精品人妻一区二区三区三区四区 | 青青草97国产精品免费观看| 99re久久精品国产| 亚洲狠狠爱一区二区三区| 国产人妖一区二区| 深夜精品寂寞黄网站在线观看| 亚洲成人不卡| 美女主播视频一区| 亚洲视频二区| 在线视频 日韩| 亚洲一区二三区| 精品国产av鲁一鲁一区| 不卡av电影院| 久久久久久爱| 青草全福视在线| 国产精品中文欧美| 三级影片在线看| 日韩欧美国产综合一区| 成人免费在线| 91成人免费看| 欧美日韩hd| 日本国产在线视频| 亚洲成av人综合在线观看| 六月婷婷中文字幕| 久久久久久69| 精品福利一区| 久久精品免费一区二区| 91一区二区在线观看| 中文字幕超碰在线| 亚洲精品美女久久| 最新日韩精品| 亚洲成人自拍| 韩国三级在线一区| 久久中文字幕在线观看| 亚洲国产精久久久久久久| 日韩电影毛片| 日韩理论片在线观看| 精品一区二区成人精品| 免费在线观看一级片| 精品国产凹凸成av人导航| 欧美男男tv网站在线播放| 午夜精品美女久久久久av福利| 奇米777欧美一区二区| 1024手机在线视频| 亚洲娇小xxxx欧美娇小| 成人做爰视频www网站小优视频| 天天人人精品| 国产成人午夜视频| www.99re7.com| 亚洲天堂av在线免费观看| 欧美少妇激情| 欧美国产综合在线| 久久―日本道色综合久久| ,一级淫片a看免费| 九九热这里只有在线精品视| 噜噜噜天天躁狠狠躁夜夜精品| 成人在线免费播放视频| 亚洲欧美激情一区二区| 四虎在线免费观看| 国产一区视频在线| 亚洲精品少妇| 免费黄色国产视频| 亚洲成人av在线播放| 久久久久黄色| heyzo亚洲| 亚洲同性gay激情无套|