理清Activity、View及Window之間關系

我的CSND博客同步發布:理清Activity、View及Window之間關系

轉載請注明出處:【huachao1001的簡書:http://www.lxweimin.com/users/0a7e42698e4b/latest_articles】

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里面的回調即可。無需關注其他細節,默認都幫我們寫好了,針對需要定制的部分我們重寫(設計模式為:模板方法模式)。

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容