每次我們創(chuàng)建一個(gè)Activity的時(shí)候都會(huì)通過setContentView( layoutResID )方法,將自定義的布局文件添加到Activity上步势。啟動(dòng)程序后我們自定義的布局就會(huì)顯示到手機(jī)上自赔。接下來我們從源碼的角度來分析一下自定義的布局文件顯示的過程妈嘹。
View的加載過程
實(shí)際開發(fā)中我們創(chuàng)建Activity一般都繼承 AppCompatActivity,但是在低版本的時(shí)候繼承Activity绍妨。所以對(duì)于setContentView( layoutResID ) 就有了兩種情況 润脸。接下來我們就根據(jù)不同的父類分析一下柬脸。
1、繼承自 AppCompatActivity?
我們先看 AppCompatActivity 中的源碼
> AppCompatActivity 中的源碼很簡(jiǎn)單毙驯。首先通過 AppCompatDelegate 的靜態(tài)方法 create( ) 創(chuàng)建了一個(gè)AppCompatDelegate 實(shí)例肖粮。并調(diào)用該實(shí)例的 setContentView 方法。?
接下來看看AppCompateDelegate的源碼
通過上面的源碼我們發(fā)現(xiàn) AppCompateDelegate 是一個(gè)抽象類尔苦,它的create方法中返回的是它的子類AppCompatDelegateImpl 的實(shí)例。
接下來就看一下 AppCompatDelegateImpl 中的方法
AppCompatDelegateImpl 的構(gòu)造方法就是初始化關(guān)聯(lián)的Context和Window行施。setContentView()方法中先創(chuàng)建一個(gè)mSubDecor(ViewGroup)并將我們自定義的布局加載到mSubDecor中的ID為content的子View中允坚。將mSubDecor添加到Window是通過createSubDecor()中mWindow的getDecorView()和setContentView()。我們知道Window是一個(gè)抽象類它的唯一子類是PhoneWindow蛾号。
接著我們?nèi)タ碢honeWindow的源碼稠项。
上面的源碼就是創(chuàng)建了一個(gè)FrameLayout類型的DecorView,然后根據(jù)不同的條件初始化一個(gè)layoutResource 資源ID鲜结,每一個(gè)layoutResource 中都會(huì)含有一個(gè)id為android.R.id.content的ViewGroup展运,將layoutResource對(duì)應(yīng)的布局add到DecorView中。mContentParent就是Id為content的ViewGroup精刷。
然后將 AppCompatDelegateImpl 中創(chuàng)建的mSubDecor添加到mContentParent中拗胜。這樣我們的布局文件就加載到Window上了。
2怒允、直接繼承Activity
此時(shí)的setContentView調(diào)用的是Activity中的埂软。那接下里看一下Activity的相關(guān)源碼
Activity中的方法很簡(jiǎn)單就是獲取了Window對(duì)象并調(diào)用了它的setContentView()方法。接下來就是PhoneWindow里面的源碼了
上面的代碼中重要的兩個(gè)步驟就是installDecor()方法纫事,第一個(gè)就是我們?cè)谏厦嬉呀?jīng)分析過的創(chuàng)建了一個(gè)DecorView對(duì)象然后根據(jù)不同的設(shè)置初始化一個(gè)layoutResource布局資源勘畔,并將該資源加載到DecorView中返回一個(gè)id為content的View即mContentParent。第二個(gè)就是將我們的布局加載到mContentParent中丽惶。
> 該文檔是自己的學(xué)習(xí)記錄如有錯(cuò)誤歡迎指出炫七。