天天看點

Android什麼時候進行View中Background的加載

對大多數Android的開發者來說,最經常的操作莫過于對界面進行布局,View中背景圖檔的加載是最經常做的。但是我們很少關注這個過程,這篇文章主要解析view中背景圖檔加載的流程。了解view中背景圖檔的加載(資源的加載)可以讓我們對資源加載的過程進行一些優化,另外當需要進行整個應用的換膚時,也可以更得心應手。

View圖檔的加載,我們最常見的就是通過在XML檔案當中進行drawable的設定,然後讓Android系統幫我們完成,或者手動寫代碼加載成Bitmap,然後加載到View上。這篇文章主要分析Android在什麼時候以及怎麼幫我們完成背景圖檔的加載的,那麼我們就從Activity.setContentView還是LayoutInflater.inflate(...)方法開始分析。

上面這麼長一串代碼,其實思路很清晰,就是針對XML檔案進行解析,然後根據XML解析出的每一個節點進行View的初始化,緊接着将View的Layout參數設定到View上,然後将View添加到它的父控件上。

為了了解View是怎麼被加載出來的,我們隻需要了解

跟進去看看。

上面代碼的重點在于try...Catch裡的内容。try包起來的東西就是對View進行初始化,注意到上面代碼中有幾個Factory,這些Factory可以在View進行初始化,也就是說其實我們可以在這裡幹預View的初始化。從上面代碼我們可以知道,如果我們自定義了一個Factory,那麼目前要初始化的View會優先被我們自定義的Factory初始化,而不通過系統預設的Factory初始化。那麼如果我們要自定義Factory,應該在哪裡定義呢?容易想到,Factory必須要趕在資源加載前自定義完成,是以我們應該在onCreate(...)的this.setContentView(...)之前設定LayoutInflater.Factory。

接下來我們看到上面函數裡面的

這段函數就是對View進行初始化,有兩種情況,一種是系統自帶的View,它在

這裡面進行初始化,因為如果是系統自帶的View,傳入的那麼一般不帶系統的字首"android.view."。另一個分支初始化的是我們自定義的View。我們跟進onCreateView看看。

從onCreateView(...)中我們知道,其實createViewFromTag(...)中對View的初始化最終都是通過createView(...)這個函數進行初始化的,不同隻在于系統控件需要通過onCreateView(...)加上字首,以便類加載器(ClassLoader)正确地通過類所在的包初始化這個類。createView(...)這個函數的思路很清晰,不看catch裡面的内容,try裡面開頭的兩個分支就是用來将所要用的類構造函數提取出來,Android系統會對使用過的類構造函數進行緩存,因為像TextView這些常用的控件可能會被使用很多次。接下來,就是通過類構造函數對View進行初始化了。我們注意到傳入構造函數的mConstructorArgs是一個包含兩個元素的數組。

那麼我們就很清楚了,它就是調用系統控件中對應兩個參數的構造函數。為了友善,我們就從最基礎的View進行分析。

由于我們隻關注View中的背景圖是怎麼加載的,注意這個函數其實就是周遊AttributeSet attrs這個東西,然後對View的各個屬性進行初始化。我們直接進入

這裡看看(TypedArray.getDrawable)。

我們發現它調用mResources.loadDrawable(...),進去看看。

就是這個函數了,所有View的背景的加載都在這裡了。這個函數的邏輯就比較複雜了,大體說來就是根據背景的類型(純顔色、定義在XML檔案中的,或者是一張靜态的背景),如果緩存裡面有,就直接用緩存裡的。

總結一下,經過上面的分析,我們知道了,Android就是在Activity.setContentView(...)中為我們進行資源檔案的加載,精确到具體的函數的話,資源檔案的加載就是在每一個被初始化的View的構造函數中進行加載的。

本文轉自陳哈哈部落格園部落格,原文連結http://www.cnblogs.com/kissazi2/p/4310055.html如需轉載請自行聯系原作者

kissazi2

繼續閱讀