1. 程式人生 > >理清Activity、View及Window之間關係

理清Activity、View及Window之間關係

ViewWindow以及Activity主要是用於顯示並與使用者互動的。這讓我們在初學的時候很容易弄混,而且無法理解他們區別以及聯絡。本文是筆者查閱相關資料後,結合自己的理解寫出來。希望能幫你梳理清楚他們各自的工作職責,以及是因為什麼需求導致了它們的出現。

1 View

從我之前寫的【從Android程式碼中來記憶23種設計模式 】這篇文章可知,View(包括ViewGroup)使用的是組合模式,即:

View組成成樹形結構,以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。

我們知道,View主要是用於繪製我們想要的結果,是一個最基本的UI元件。

2 Window

2.1 Window的基本理解

簡單地說,Window表示一個視窗,一般來說,Window大小取值為螢幕大小。但是這不是絕對的,如對話方塊、Toast等就不是整個螢幕大小。你可以指定Window的大小。Window包含一個View tree和視窗的layout引數。

感覺Window的理解比較抽象,我個人的理解是,Window相當於一個容器,裡面“盛放”著很多View,這些View是以樹狀結構組織起來的。

如果你還是無法理解的話,你就把Window當成是顯示器,顯示器有大有小(對應Window有大有小),View是顯示器裡面具體顯示的內容。

2.2 Window物件有存在的必要嗎?

我個人長期有個困惑:Window能做的事情,View物件基本都能做:像什麼觸控事件啊、顯示的座標及大小啊、管理各個子View啊等等。View已經這麼強大了,為什麼還多此一舉,加個Window物件。可能有人會說因為WindowManager管理的就是Window物件呀,那我想問,既然這樣,Android系統直接讓WindowManager去管理View不就好了?讓View接替Window的工作,把Window所做的事情都封裝到View裡面不好嘛?(至少免去了我們去理解抽象的Window,,,,O__O “…)。或許又有人說,View負責繪製顯示內容,Window負責管理View,各自的工作職責不同。可是我想說,Window所做的大部分工作,View裡面都有同樣(或類似)的處理。這依然無法說服我!

關於Window存在的必要,我查了國內外各種資料,最後有了我個人的理解(如果有錯也歡迎評論糾正~)。在後面小節裡面,我會結合我個人的理解來解釋。在解釋之前,我們需要了解Window繪製過程。

2.3 Window繪製過程

在理解Window繪製過程之前,首先,我們需要知道Surface,在Window中持有一個Surface,那麼什麼是Surface呢?

Surface其實就是一個持有畫素點矩陣的物件,這個畫素點矩陣是組成顯示在螢幕的影象的一部分。我們看到顯示的每個Window(包括對話方塊、全屏的Activity、狀態列等)都有他自己繪製的Surface。而最終的顯示可能存在Window之間遮擋的問題,此時就是通過Surface Flinger物件渲染最終的顯示,使他們以正確的Z-order顯示出來。一般Surface擁有一個或多個快取(一般2個),通過雙快取來重新整理,這樣就可以一邊繪製一邊加新快取。

WindowManager為每個Window建立Surface物件,然後應用就可以通過這個Surface來繪製任何它想要繪製的東西。而對於WindowManager來說,這只不過是一塊矩形區域而已。

前面我們說過,ViewWindow裡面用於互動的UI元素。Windowattach一個View Tree,當Window需要重繪(如,當View呼叫invalidate)時,最終轉為WindowSurfaceSurface被鎖住(locked)並返回Canvas物件,此時View拿到Canvas物件來繪製自己。當所有View繪製完成後,Surface解鎖(unlock),並且post到繪製快取用於繪製,通過Surface Flinger來組織各個Window,顯示最終的整個螢幕。

2.4 關於Window物件存在的必要

以下是我個人理解!

現在我們知道了Window繪製過程,其實,站在系統的角度來考慮,一個Window物件代表一塊顯示區域,系統不關心Window裡面具體的繪製內容,也不管你Window怎麼去繪製,反正只給你提供可以在這塊區域上繪製圖形的Surface物件,你Window物件怎麼畫是你的事情!

換句話說,站在系統的角度上看,系統是“不知道”有View物件這個說法的!作為系統,我有自己的驕傲,不去管你Window如何搬磚、如何砌牆,只給你地皮。而這時,Window為了繪製出使用者想要的元件(按鈕、文字、輸入框等等),系統又不給我!沒事,那我自己定義,於是就定義了View機制,給每個View提供Canvas,讓不同的View自己繪製具有自己特色的元件。同時,為了更好的管理View,通過定義ViewGroup,等等。

相信看到這,你就知道為什麼需要Window了,當然了,本文並不是去糾纏要不要Window物件這個問題。而是通過這個問題,讓我們理清ViewWindow的區別。這才是重點!到這裡,如果理由說服不了你,那你就不要去糾纏了。至少,你已經理清了ViewWindow之間的關係了,這就夠了!

3 Activity

3.1 Activity基本理解

對於開發人員來說,一個Activity就“相當於”一個介面(通過setContentView指定具體的View)。我們可以直接在Activity裡處理事件,如onKeyEvent,onTouchEvent等。 並可以通過Activity維護應用程式的生命週期。

3.2 Activity有存在的必要嗎?

同樣,我們還是以是否存在這個問題為切入點,去理清ActivityWindow關係。

前面我們知道,Window已經是系統管理的視窗介面。那麼為什麼還需要Activity呢?我們把Activity所做的事情,全部封裝到Window不就好了?

其實,本質上講,我們要顯示一個窗口出來,的確可以不需要Activity。懸浮視窗中不就是沒有使用Activity來顯示一個懸浮窗嗎?既然如此,Window(以及View)能處理點選事件以及封裝各種邏輯,那為啥還需要Activity呢?

個人理解:

Android中的應用中,裡面對各個視窗的管理相當複雜(任務棧、狀態等等),Android系統當然可以不用Activity,讓使用者自己直接操作Window來開發自己的應用。但是如果讓使用者自己去管理這些Window,先不說工作量,光讓使用者自己去實現任務棧這點,有幾個人能寫的出來。為了讓大家能簡單、快速的開發應用,Android通過定義Activity,讓Activity幫我們管理好,我們只需簡單的去重寫幾個回撥函式,無需直接與Window物件接觸。各種事件也只需重寫Activity裡面的回撥即可。無需關注其他細節,預設都幫我們寫好了,針對需要定製的部分我們重寫(設計模式為:模板方法模式)。

最後,如果有理解上的錯誤,也歡迎大家糾正。我會針對大家的意見,不斷更新修改。