Android 之Activity、Window、View之間的關係

一、概述
Activity 可以說是應用程序的載體(也可以理解爲界面的載體,但是不界面),用戶能夠在上面繪製界面(Activity本身不繪製界面),並提供用戶處理事件的API,維護應用程序的生命週期(Android應用程序是由多個 Activity 堆積而成,而各個 Activity 又有其獨立的生命週期)。
Activity內部組合了一個Window(這是一個抽象類,具體是PhoneWindow)對象。我們自己寫的擴展一個Activity時,在onCreate 方法中調用 setContentView,實際上是調用Window對象的 setContentView,所以說界面繪製全部是由Window類的實現類(PhoneWindow類)來完成的。

二、源碼分析
1 . 跟蹤源碼進入到 Activity 中看到 setContentView的實現如下:

public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
     initActionBar();
 }

看第二行代碼,先得到一個 Window 對象。

public Window getWindow() {
        return mWindow;
     }

getWindow 很簡單只是返回一個 對象而已,那麼,Window對象到底是在哪兒實例化的呢?
  我們可以看看,Activity 中的 attach 方法,這裏面得到了一個 Window 對象

mWindow = PolicyManager.makeNewWindow(this);

2 . 由Activity中的 setContentView 方法可以看到,界面繪製並不是由 Activity 完成的,他是調用了 Window 類的 setContentView 來實現的。所以我們就去看看 Window 類的代碼:

public abstract void setContentView(int layoutResID);

Window 中有一個 DecorView,可以理解爲“ViewRoot”,引號是說其實這個“ViewRoot”是一個View或者說ViewGroup,是最初始的根視圖。構建視圖就是向這裏面添加。所以到這裏大概可以知道,installDecor 方法大概是 構建一個根視圖。

三、總結
這裏寫圖片描述
Activity:是Android 四大組件之一, 是存放View對象的容器,也是我們界面的載體,可以用來展示一個界面。它有一個SetContentView()方法 ,可以將我們定義的佈局設置到界面上。
View:就是一個個視圖的對象,實現了KeyEvent.Callback和Drawable.Callback。
Window:是一個抽象類,是一個頂層的窗口,它的唯一實例是PhoneWindow它提供標準的用戶界面策略,如背景、標題、區域,默認按鍵處理等。

這裏寫圖片描述

Activity創建時系統會調用其 attach 方法,將其添加到ActivityThread當中,在attach方法中創建了一個window對象。
  我們知道Window組合了一個 DocerView, 當用戶調用 setContentView 的時候會把一棵 View 樹仍給DocerView。 View樹是已經創建好的實例對象,所以我們要研究 DocerView是個什麼東西,它是如何被創建的。
  我們回頭看看Window實現裏邊的setContentView方法,代碼中有一個 installDecor 方法,這個方法中有一個 generateDecor。 generateDecor直接new了一個DecorView對象

protected DecorView generateDecor() {
        return new DecorView(getContext(), -1);
 }

當 DocerView 被創建後,就會調用 mContentParent.addView(view, params); 來將 view 添加到 DocerView當中。
最後總結一下:

  Activity在onCreate時調用attach方法,在attach方法中會創建window對象。window對象創建時並沒有創建 DocerView 對象。用戶在Activity中調用setContentView,然後調用window的setContentView,這時會檢查DecorView是否存在,如果不存在則創建DecorView對象,然後把用戶自己的 View 添加到 DecorView 中。
  
總結起來說就是 Activity會調用PhoneWindow的setContentView()將layout佈局添加到DecorView上,而此時的DecorView就是那個最底層的View。然後通過LayoutInflater.infalte()方法加載佈局生成View對象並通過addView()方法添加到Window上,(一層一層的疊加到Window上)所以,Activity其實不是顯示視圖,Window纔是真正的顯示視圖。
注:一個Activity構造的時候只能初始化一個Window(PhoneWindow),另外這個PhoneWindow有一個View容器 mContentParent,這個
View容器是一個ViewGroup,是最初始的跟視圖,然後通過addView方法將View一個個層疊到mContentParent上,這些層疊的View最終放在Window這個載體上面。

轉載自> http://www.cnblogs.com/kest/p/5141817.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章