你們都知道Android中加載view是從Activity的onCreate方法調用setContentView開始的,那麼View的具體加載過程又是怎麼的呢?這一節咱們作一下分析。java
首先追蹤一下代碼:android
Activity中:git
public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); } public Window getWindow() { return mWindow; } final void attach { mWindow = PolicyManager.makeNewWindow(this); }
Activity在調用onCreate()以前會調用attach()初始化mWindow,這篇文章中,咱們先無論attach()是誰調用的,也無論他是怎麼被調用的。只分析一下view的加載過程。下面是PolicyManager方法:github
PolicyManager:
ide
// sPolicy爲Policy對象,實現了接口IPolicy public static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context); }
再看Policy類中的代碼 佈局
// 這裏就是返回了一個PhoneWindow對象 public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context); }
從而可知 Activity中的setContentView 最終調用的是PhoneWindow類中的 setContentView. this
@Override public void setContentView(int layoutResID) { if (mContentParent == null) { installDecor(); } else { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); } }
installDecor()初始化了DecorView、mContentParent還有title(3.0之後的ActionBar)。DecorView是繼承自FrameLayout的PhoneWindow的內部類。
spa
installDecor()中的代碼:
.net
if (mContentParent == null) { mContentParent = generateLayout(mDecor);
protected ViewGroup generateLayout(DecorView decor) { View in = mLayoutInflater.inflate(layoutResource, null); decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); }
從上面的代碼看出,加載的視圖添加到了DecorView上,這樣Activitty加載視圖的過程就完成了。試圖加載過程當中出現了Activity、Window、View。Activity是Android應用程序的載體,容許用戶在其上建立一個用戶界面,並提供用戶處理事件的API,如onKeyEvent, onTouchEvent等, 並維護應用程序的生命週期。每個Activity組件都有一個關聯的Window對象,用來描述一個應用程序窗口。每個應用程序窗口內部又包含有一個View(DecorView)對象,用來描述應用程序窗口的視圖。應用程序窗口視圖是真正用來實現UI內容和佈局的,也就是說,每個Activity組件的UI內容和佈局都是經過與其所關聯的一個Window對象的內部的一個View對象來實現的。code