我的CSND博客同步發(fā)布:理清Activity汤求、View及Window之間關(guān)系
轉(zhuǎn)載請注明出處:【huachao1001的簡書:http://www.reibang.com/users/0a7e42698e4b/latest_articles】
View
挨稿、Window
以及Activity
主要是用于顯示并與用戶交互的。這讓我們在初學(xué)的時候很容易弄混鸟妙,而且無法理解他們區(qū)別以及聯(lián)系焦人。本文是筆者查閱相關(guān)資料后挥吵,結(jié)合自己的理解寫出來。希望能幫你梳理清楚他們各自的工作職責(zé)花椭,以及是因?yàn)槭裁葱枨髮?dǎo)致了它們的出現(xiàn)忽匈。
1 View
從我之前寫的【從Android代碼中來記憶23種設(shè)計模式 】這篇文章可知,View
(包括ViewGroup
)使用的是組合模式矿辽,即:
將
View
組成成樹形結(jié)構(gòu)丹允,以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對單個對象和組合對象的使用具有一致性袋倔。
我們知道雕蔽,View
主要是用于繪制我們想要的結(jié)果,是一個最基本的UI
組件奕污。
2 Window
2.1 Window的基本理解
簡單地說萎羔,Window
表示一個窗口,一般來說碳默,Window
大小取值為屏幕大小。但是這不是絕對的缘眶,如對話框嘱根、Toast
等就不是整個屏幕大小。你可以指定Window的大小巷懈。Window
包含一個View tree
和窗口的layout
參數(shù)该抒。
感覺Window
的理解比較抽象,我個人的理解是顶燕,Window
相當(dāng)于一個容器凑保,里面“盛放”著很多View
,這些View
是以樹狀結(jié)構(gòu)組織起來的涌攻。
如果你還是無法理解的話欧引,你就把Window
當(dāng)成是顯示器,顯示器有大有锌一选(對應(yīng)Window
有大有兄ゴ恕),View
是顯示器里面具體顯示的內(nèi)容因痛。
2.2 Window對象有存在的必要嗎婚苹?
我個人長期有個困惑:Window
能做的事情,View
對象基本都能做:像什么觸摸事件啊鸵膏、顯示的坐標(biāo)及大小啊膊升、管理各個子View
啊等等。View
已經(jīng)這么強(qiáng)大了谭企,為什么還多此一舉廓译,加個Window
對象评肆。可能有人會說因?yàn)?code>WindowManager管理的就是Window
對象呀责循,那我想問糟港,既然這樣,Android
系統(tǒng)直接讓WindowManager
去管理View
不就好了院仿?讓View
接替Window
的工作秸抚,把Window
所做的事情都封裝到View
里面不好嘛?(至少免去了我們?nèi)ダ斫獬橄蟮?code>Window歹垫,剥汤,,排惨,O__O "…)吭敢。或許又有人說暮芭,View負(fù)責(zé)繪制顯示內(nèi)容鹿驼,Window負(fù)責(zé)管理View,各自的工作職責(zé)不同辕宏⌒笪可是我想說,Window所做的大部分工作瑞筐,View里面都有同樣(或類似)的處理凄鼻。這依然無法說服我!
關(guān)于Window
存在的必要聚假,我查了國內(nèi)外各種資料块蚌,最后有了我個人的理解(如果有錯也歡迎評論糾正~)。在后面小節(jié)里面膘格,我會結(jié)合我個人的理解來解釋峭范。在解釋之前,我們需要了解Window
繪制過程闯袒。
2.3 Window繪制過程
在理解Window
繪制過程之前虎敦,首先,我們需要知道Surface
政敢,在Window
中持有一個Surface
其徙,那么什么是Surface
呢?
Surface
其實(shí)就是一個持有像素點(diǎn)矩陣的對象喷户,這個像素點(diǎn)矩陣是組成顯示在屏幕的圖像的一部分唾那。我們看到顯示的每個Window
(包括對話框、全屏的Activity
、狀態(tài)欄等)都有他自己繪制的Surface
闹获。而最終的顯示可能存在Window
之間遮擋的問題期犬,此時就是通過Surface Flinger
對象渲染最終的顯示,使他們以正確的Z-order
顯示出來避诽。一般Surface
擁有一個或多個緩存(一般2個)龟虎,通過雙緩存來刷新,這樣就可以一邊繪制一邊加新緩存沙庐。
WindowManager
為每個Window
創(chuàng)建Surface
對象鲤妥,然后應(yīng)用就可以通過這個Surface
來繪制任何它想要繪制的東西。而對于WindowManager
來說拱雏,這只不過是一塊矩形區(qū)域而已棉安。
前面我們說過,View
是Window
里面用于交互的UI
元素铸抑。Window
只attach
一個View Tree
贡耽,當(dāng)Window
需要重繪(如,當(dāng)View
調(diào)用invalidate
)時鹊汛,最終轉(zhuǎn)為Window
的Surface
蒲赂,Surface
被鎖住(locked
)并返回Canvas
對象刁憋,此時View
拿到Canvas
對象來繪制自己凳宙。當(dāng)所有View
繪制完成后,Surface
解鎖(unlock
)职祷,并且post
到繪制緩存用于繪制,通過Surface Flinger
來組織各個Window
届囚,顯示最終的整個屏幕有梆。
2.4 關(guān)于Window對象存在的必要
以下是我個人理解!
現(xiàn)在我們知道了Window
繪制過程意系,其實(shí)泥耀,站在系統(tǒng)的角度來考慮,一個Window
對象代表一塊顯示區(qū)域蛔添,系統(tǒng)不關(guān)心Window
里面具體的繪制內(nèi)容痰催,也不管你Window
怎么去繪制,反正只給你提供可以在這塊區(qū)域上繪制圖形的Surface
對象迎瞧,你Window
對象怎么畫是你的事情夸溶!
換句話說,站在系統(tǒng)的角度上看凶硅,系統(tǒng)是“不知道”有View
對象這個說法的缝裁!作為系統(tǒng),我有自己的驕傲足绅,不去管你Window
如何搬磚捷绑、如何砌墻韩脑,只給你地皮。而這時粹污,Window
為了繪制出用戶想要的組件(按鈕段多、文字、輸入框等等)壮吩,系統(tǒng)又不給我进苍!沒事,那我自己定義粥航,于是就定義了View
機(jī)制琅捏,給每個View
提供Canvas
,讓不同的View
自己繪制具有自己特色的組件递雀。同時柄延,為了更好的管理View
,通過定義ViewGroup
缀程,等等搜吧。
相信看到這,你就知道為什么需要Window
了杨凑,當(dāng)然了滤奈,本文并不是去糾纏要不要Window
對象這個問題。而是通過這個問題撩满,讓我們理清View
與Window
的區(qū)別蜒程。這才是重點(diǎn)!到這里伺帘,如果理由說服不了你昭躺,那你就不要去糾纏了。至少伪嫁,你已經(jīng)理清了View
與Window
之間的關(guān)系了领炫,這就夠了!
3 Activity
3.1 Activity基本理解
對于開發(fā)人員來說张咳,一個Activity
就“相當(dāng)于”一個界面(通過setContentView
指定具體的View
)帝洪。我們可以直接在Activity里處理事件,如onKeyEvent
,onTouchEvent
等脚猾。 并可以通過Activity
維護(hù)應(yīng)用程序的生命周期葱峡。
3.2 Activity有存在的必要嗎?
同樣婚陪,我們還是以是否存在這個問題為切入點(diǎn)族沃,去理清
Activity
與Window
關(guān)系。
前面我們知道,Window
已經(jīng)是系統(tǒng)管理的窗口界面脆淹。那么為什么還需要Activity
呢常空?我們把Activity
所做的事情,全部封裝到Window
不就好了盖溺?
其實(shí)漓糙,本質(zhì)上講,我們要顯示一個窗口出來烘嘱,的確可以不需要Activity
昆禽。懸浮窗口中不就是沒有使用Activity
來顯示一個懸浮窗嗎?既然如此蝇庭,Window
(以及View
)能處理點(diǎn)擊事件以及封裝各種邏輯醉鳖,那為啥還需要Activity呢?
個人理解:
Android
中的應(yīng)用中哮内,里面對各個窗口的管理相當(dāng)復(fù)雜(任務(wù)棧盗棵、狀態(tài)等等),Android
系統(tǒng)當(dāng)然可以不用Activity
北发,讓用戶自己直接操作Window
來開發(fā)自己的應(yīng)用纹因。但是如果讓用戶自己去管理這些Window
,先不說工作量琳拨,光讓用戶自己去實(shí)現(xiàn)任務(wù)棧這點(diǎn)瞭恰,有幾個人能寫的出來。為了讓大家能簡單狱庇、快速的開發(fā)應(yīng)用惊畏,Android
通過定義Activity,讓Activity
幫我們管理好密任,我們只需簡單的去重寫幾個回調(diào)函數(shù)陕截,無需直接與Window
對象接觸。各種事件也只需重寫Activity
里面的回調(diào)即可批什。無需關(guān)注其他細(xì)節(jié),默認(rèn)都幫我們寫好了社搅,針對需要定制的部分我們重寫(設(shè)計模式為:模板方法模式)驻债。