項目地址:ListViewVisualizationgit
本文不涉及 ListView 緩存機制的源碼探析,關於 ListView 的緩存機制郭霖前輩的《Android ListView工做原理徹底解析,帶你從源碼的角度完全理解》已經分析的很通徹了,同理網上也有不少文章了。本文不針對 ListView 的緩存機制作介紹,對於這塊還不夠了解的朋友能夠閱讀上方郭霖前輩的文章。另外再配上騰訊 Bugly 的圖:github
對於像 ListView/RecyclerView 這種級別 View 的源碼是長篇且晦澀的,連郭霖前輩本身也說過 「沒過幾個月時間我就把當初梳理清晰的源碼又忘的一乾二淨」
。且網上的文章都是針對代碼闡述的,實在是有些難以理解,且部分知識點並未涉及(例如僅針對 ViewType 只有一種狀況的情形作說明,多 ViewType 情形下緩存機制少見闡述)。筆者遇到這些問題時候仍是很頭疼的,因而就將 ListView 的緩存機制給可視化,再針對各個情形加以總結,相信能幫助到不少對 ListView 緩存機制不太熟悉的讀者們。數組
項目地址:ListViewVisualization或者你能夠直接安裝:apk。 在手摸手解析以前,須要說起到 RecycleBin 中的幾個字段 ,這些字段在郭霖前輩的文章中基本都有所說起,實際上掌握了這些字段在 ListView 緩存機制中變換的狀況,筆者認爲對 ListView 的緩存機制瞭解就算是比較通徹的了——緩存
文章中說起的部分名詞:項目中 ListView 使用了兩個 ViewType,也就是有兩種佈局,其中第一種筆者在文中說起到時命名爲 Item1,第二種稱爲 Item2。app
mActiveViews:長度爲4。在筆者的手機上初始化時屏幕上只能容下4個 View mScrapViews:長度爲2。筆者設置了兩種 ViewType,因此須要有兩套緩存 View 的 ArrayList
當 『1』 被移出屏幕的時候,mCurrentScrap/mScrapViews[0] 就要動手將它緩存起來啦,做爲下一個進入屏幕的 View 的複用。在圖上此時也多出了一句 the last one of mCurrentScrap's type is ItemX---number
,爲何要關注 mCurrentScrap 的最後一個值?由於 RecycleBin 在滑動區域都是 Item1 的狀況下,取出緩存的方式就是從末尾獲取一個 View,因此咱們須要關注一下末尾 View 的類型,可是實際上在整個過程當中該值的意義也並不大,純粹是爲了展現離屏 Item 信息。至於 ItemX 後面的數字,則是廢棄 View 中 TextView 中所顯示的 text 了。因此第一個緩存是一個 Item1 類型的 TextView 顯示爲 1 的 View 被移出屏幕了。.net
同理:當『2』被滑出屏幕的時候,『2』這個 View 將會被緩存起來,此時屏幕上應該顯示了 the last one of mCurrentScrap's type is Item1---2
,各位讀者能夠試試。debug
屏幕下滑沒多少就會忽然發現 mCurrentScrap/mScrapView[0] 爲 0 啦,這說明此時 RecycleBin 中沒有緩存!由於此時屏幕中已經顯示了 『2』~『6』共 5 個 View 了,以前的 『1』 已經被 『6』 複用了,因此不存在還有緩存了。實際上針對於 ViewType 只有一種的狀況來講,RecycleBin 機制中的 mCurrentScrap/mScrapViews[0] 的大小永遠是1。由於它至多隻須要緩存一個 View,由於屏幕內容數量的最大值一定爲初始時屏幕內容數量值 + 1,拿筆者的手機舉例來講,初始值爲4,屏幕內容數量的最大值則爲 5。code
一切都在掌控以內。cdn
當『14』被移出後,mCurrentScrap/mScrapViews[0] 的 size 從百年不變的 1 變成了 2。爲何?由於『13』 用不上了,新出來的 View 是 Item2 而不是 Item1,因此緩存只能無奈的加加加,而不能被複用。咱們不妨移動到全屏爲 Item2 ——
直至『17』移出屏幕,mCurrentScrap/mScrapViews[0] 的大小最終達到了 5。