ListView原始碼解析

2021-10-22 06:57:45 字數 2486 閱讀 6267

優化3 分段載入

4 分頁載入

再說listview之前首先需要說一下recyclerbin機制

這個機制是保證listview能夠實現成百上千條資料也不會oom的關鍵,listview和gridview都使用的是這個機制。

他的核心就是幾個方法,fillactiveviews()用來往activeviews這個陣列裡面存view,而getactiveviews和他相反,是用來取出view的。還有addscrapview是用來快取廢棄的view,getscrapview是用來取出快取。

listview的核心就在滑動重新整理上,比如說我們現在有1000條資料,但是第一屏只用10條,那麼listview中就只有10個子view而已,那剩下的990條子view是怎麼工作的呢?

核心就在abslistview類中的ontouchevent中。

這個方法中的action_down事件中呼叫了乙個方法叫做trackmotionscroll,這個方法一旦我們手指在螢幕上稍微有一點移動就會呼叫這個方法,如果是正常情況下,手指在螢幕上滑動的話,這個方法會被呼叫很多次。

這個方法接收了兩個引數,乙個是我們手指從按下當當前位置的距離deltay,和上次觸發event事件手指在y軸上的改變量incrementaldeltay,可以通過incrementdeltay的正負值來判斷手指是向上滑還是向下滑。

當listview向下滑動的時候,就會進入乙個for迴圈,在這個迴圈中會從上到下依次獲取子view。如果該子view的bottom值已經小於top值了,那就說明這個子view已經被移除了螢幕頂部,所以這個子view就可以被**了,就會呼叫我們之前說到的recyclebin的addscrapview方法新增到廢棄快取中去,並將count加1。如果是下滑原理一樣,反過來就行了。

接下來就是根據當前計數器的值進行乙個detach操作,他的作用就是將所有移出螢幕的子view全部detach掉。在listview的概念中,看不到的view就沒有必要為他儲存。接著呼叫offsetchildrentopandbottom方法,將incrementdeltay傳入,讓listview中的子view都按照傳入的值進行相應的偏移

如果listview中最後乙個view的底部已經移入了螢幕,或者listview中第乙個view移入了螢幕,就會呼叫fillgap方法,而這個方法中又會呼叫makeandaddview方法,由於這次activeviews裡面沒有了資料,就會呼叫obtainview方法,而在這個方法中,會呼叫getscrapview方法來從廢棄快取中獲取乙個view,這塊就形成了乙個生產者消費者關係:一旦有任何子view被移出了螢幕,就把他加入到廢棄快取中去,而一旦有新的資料需要在螢幕中顯示,就從廢棄快取中獲取view。這也就是listview神奇的地方,來來回回其實就那麼幾個子view,你所看到的都是將子view復用所形成的超多個子view的假象,也正因為此,listview不管我們新增多少資料都不會oom。

這個是最簡單的優化。在adapter類的getview中通過判斷當前傳入的convertview是否為null,如果為null,就需要通過view.inflater再建立乙個檢視出來, 如果不為null的話,新的view可以通過復用的方式使用convertview,以減少view的建立。

第一種有乙個缺點就是每次都需要再findviewbyid,然後再對控制項賦值,這樣會減慢載入速度。我們可以建立乙個內部類viewholder,將item中所有控制項都封裝進入。然後當convertview為null的時候,就把findviewbyid找到的控制項賦給viewholder中對應的變數,然後再通過settag方法將view和viewholder繫結在一起。如果convertview不為null的時候,就直接gettag。然後再設定顯示內容然後return。

如果不重用 convertview 不會出現錯位現象, 重用 convertview 但沒有非同步操作也不會有問題。

ablistview中獲取getview()和滑動操作是非同步進行的,其中滑動操作在乙個flingrunnable的支線程中執行,所以這就導致了在listview在滑動時可能已經滑動到了第十行,雖然它們位置不同,但都是共用的同乙個imageview例項,第二行的資料這時就被直接使用了,這就是導致資料載入錯亂的根本原因。

知道了錯亂的原因,那麼解決起來應該就很簡單了,我們可以給設定tag來避免資料錯亂

有些情況下我們需要載入網路中的資料,顯示到listview,而往往此時都是資料量比較多的一種情況,如果資料有1000條,沒有優化過的listview都是會一次性把資料全部載入出來的,很顯然需要一段時間才能載入出來,我們不可能讓使用者面對著空白的螢幕等好幾分鐘,那麼這時我們可以使用分段載入,比如先設定每次載入資料10條,當使用者滑動listview到底部的時候,我們再載入20條資料出來,然後使用adapter重新整理listview,這樣使用者只需要等待10條資料的載入時間,這樣也可以緩解一次性載入大量資料而導致oom崩潰的情況。

實現方法:

設定滑動監聽,當滑動時取消載入,當滑動停止時再去載入。

Fabric 原始碼解析 原始碼目錄解析

這裡對重要的一些目錄進行說明 bccsp 與密碼學 加密 簽名 證書等等 相關的加密服務 將fabric中用到的密碼學相關的函式抽象成了一組介面,便於拓展。bddtests 一種新型的軟體開發模式 行為驅動開 需求 開發 common 一些公共庫 錯誤處理 日誌處理 賬本儲存 策略以及各種工具等等 ...

Spring原始碼解析之 Aop原始碼解析(2)

spring aop 更多的是oop開發模式的乙個補充,幫助oop以更好的方式來解決對於需要解決業務功能模組之上統一管理 的功能 以一副圖來做為aop功能的說明更直觀些。對於類似系統的安全檢查,系統日誌,事務管理等相關功能,物件導向的開發方法並沒有更好的解決方法 aop引入了一些概念。更多的是spr...

Integer原始碼解析

public class test else integer i3 200 integer i4 200 if i3 i4 else 結果為 原因integer 類會快取 128 到 127 之間的整數 但是如果new interger的話就是不同的物件了 源 分析 如果是在 128到正的127之間...