天天看點

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

要說Android view加載流程,首先,我們需要清楚的了解什麼是View、Window、Activity 以及三着有着什麼樣的關系。

一、什麼是Activity?

看看源碼中對Activity的描述:

* An activity is a single, focused thing that the user can do.  Almost all      
* activities interact with the user, so the Activity class takes care of      
* creating a window for you in which you can place your UI with      
* {@link #setContentView}.  While activities are often presented to the user      
* as full-screen windows      

Activity是 使用者操作的可視化界面;它為使用者提供了一個放置視圖和互動操作的視窗。采用setContentView的方法提供。

是以,可以了解Activity、Window、View三者關系為。Activity提供Window ,View被添加到Window中。

以刷牆舉例:

Activity可以了解為房間,Window就是房間内的牆面, 我們在牆面上可以刷各種不同的圖案,這些圖案就是View。

二、Activity View的加載流程

1、Activity在被建立之初,調用了attach方法,這個時候,為Activity建立了一個PhoneWindow, 并且為PhoneWindow設定了事件互動的回掉。

2、緊接着Activity的onCreate()方法被回掉。這裡也就到了我們經常複寫方法,我們在OnCreate()之中,調用setContentView(id)。

3、在setContentView(), PhoneWindow 建立了一個頂級視圖 DecorView (FrameLayout)的子類。

4、緊接着,DecorView會依據一些feature(類似NO_ACTICON_BAR)來,添加一個layout。這個Layout中包含了Title、content。其中content也是FrameLayout,也就是我們在setContentView(id),将視圖添加的父容器。

是以我們必須要在setContentView之前設定

實作全屏      
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  WindowManager.LayoutParams.FLAG_FULLSCREEN);      
實作無标題欄(但有系統自帶的工作列):      
requestWindowFeature(Window.FEATURE_NO_TITLE);        

更加直覺的可以看作為:

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

我門操作的所有View都是在contentView這裡,contentView作為父容器,其id為固定的 android.id.content.

三、源碼分析

檢視Activity的attach 方法

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

可以看出這個時候建立了PhoneWindow的執行個體。

接下來,Activity生命周期會到onCreate(),我們在onCreate方法中,調用了setContentView方法

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

跟進setContentView方法,看看源碼做了什麼

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

繼續,調用了PhoneWindow的setContentView

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

重點在installDecor()方法:

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

我們看看 mDecor 的初始化:

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

mDecor 是DecorView的執行個體,DecorView又是FrameLayout的子類:

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

我們回到installDecor方法,繼續往下檢視generateLayout:

generateLayout()方法中,先對一系列的feature進行了判讀對比,和backgroud 顔色擷取等,然後通過以上feature加載一個layoutRes到decorView中。

然後在layoutRes,中找到 ID_ANDROID_CONTENT = com.android.internal.R.id.content 的FrameLayout 作為我們setContentView 的容器。

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

此處框出的位置,就是我們傳回的父容器。這裡很明顯傳回的是ViewGroup, 就怎麼認定他是FrameLayout這個子類呢??

很簡單,對上訴的幾個resource點選檢視,發現全都是FrameLayout..

再次回到PhoneWindow#installDecor, 可以看到

mContentParent = generateLayout(mDecor);      

在PhoneWindow#installDecor繼續往下看,可以看到對Title Icon這些的指派之類。

傳回到setContentView中:将我們的layoutId 解析為View,加入到mContentParent。

mLayoutInflater.inflate(layoutResID, mContentParent);      

我們在看看看LayoutInflater.inflate的過程:

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

其實就是解析XML ,更加xml解析為View并添加到視圖關系中。

問題:view是如何根據我們的類名不同而建立的各種不同的View呢?

繼續跟進以上代碼,最終發現調用到了

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

依據類名反射建立, 到此,真個View的加載過程就完成了。

Android View的加載流程一、什麼是Activity?二、Activity View的加載流程三、源碼分析總結:

總結:

1、Activity在被建立之初,調用了attach方法,這個時候,為Activity建立了一個PhoneWindow, 并且為PhoneWindow設定了事件互動的回掉。

2、緊接着Activity的onCreate()方法被回掉。這裡也就到了我們經常複寫方法,我們在OnCreate()之中,調用setContentView(id)。

3、在setContentView(), PhoneWindow 建立了一個頂級視圖 DecorView (FrameLayout)的子類。

4、緊接着,DecorView會依據一些feature(類似NO_ACTICON_BAR)來,添加一個layout。這個Layout中包含了Title、content。

其中content也是FrameLayout

5、然後再将我們的setContentView()的layoutId解析為View 添加到這個contentView中。

接下來, 又是如何被繪制到螢幕上的呢?請敬請等待下一章 Android View的繪制流程。

繼續閱讀