我的CSND博客同步發布:理清Activity、View及Window之間關系
轉載請注明出處:【huachao1001的簡書:http://www.lxweimin.com/users/0a7e42698e4b/latest_articles】
View
、Window
以及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
來說,這只不過是一塊矩形區域而已。
前面我們說過,View
是Window
里面用于交互的UI
元素。Window
只attach
一個View Tree
,當Window
需要重繪(如,當View
調用invalidate
)時,最終轉為Window
的Surface
,Surface
被鎖住(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
對象這個問題。而是通過這個問題,讓我們理清View
與Window
的區別。這才是重點!到這里,如果理由說服不了你,那你就不要去糾纏了。至少,你已經理清了View
與Window
之間的關系了,這就夠了!
3 Activity
3.1 Activity基本理解
對于開發人員來說,一個Activity
就“相當于”一個界面(通過setContentView
指定具體的View
)。我們可以直接在Activity里處理事件,如onKeyEvent
,onTouchEvent
等。 并可以通過Activity
維護應用程序的生命周期。
3.2 Activity有存在的必要嗎?
同樣,我們還是以是否存在這個問題為切入點,去理清
Activity
與Window
關系。
前面我們知道,Window
已經是系統管理的窗口界面。那么為什么還需要Activity
呢?我們把Activity
所做的事情,全部封裝到Window
不就好了?
其實,本質上講,我們要顯示一個窗口出來,的確可以不需要Activity
。懸浮窗口中不就是沒有使用Activity
來顯示一個懸浮窗嗎?既然如此,Window
(以及View
)能處理點擊事件以及封裝各種邏輯,那為啥還需要Activity呢?
個人理解:
Android
中的應用中,里面對各個窗口的管理相當復雜(任務棧、狀態等等),Android
系統當然可以不用Activity
,讓用戶自己直接操作Window
來開發自己的應用。但是如果讓用戶自己去管理這些Window
,先不說工作量,光讓用戶自己去實現任務棧這點,有幾個人能寫的出來。為了讓大家能簡單、快速的開發應用,Android
通過定義Activity,讓Activity
幫我們管理好,我們只需簡單的去重寫幾個回調函數,無需直接與Window
對象接觸。各種事件也只需重寫Activity
里面的回調即可。無需關注其他細節,默認都幫我們寫好了,針對需要定制的部分我們重寫(設計模式為:模板方法模式)。