在前一個系列文章中,咱們從個體的角度來分析了Android應用程序窗口的實現框架。事實上,若是咱們從總體的角度來看,Android應用程序窗口的實現要更復雜,由於它們的類型和做用不一樣,且會相互影響。在Android系統中,對系統中的全部窗口進行管理是窗口管理服務WindowManagerService的職責。在本文中,咱們就將簡要介紹WindowManagerService的職能以及制定學習計劃。算法
咱們知道,在Android系統中,同一時刻,只有一個Activity窗口是激活的,可是,對於WindowManagerService服務來講,這並不意味着它每次只須要管理一個Activity窗口,例如,在兩個Activity窗口的切換過程當中,先後兩個Activity窗口實際上都是可見的。即便在只有一個Activity窗口是可見的時候,WindowManagerService服務仍然須要同時管理着多個窗口,這是由於可見的Activity窗口可能還會被設置了壁紙窗口(Wallpaper Winodw)或者彈出了子窗口(Sub Window),以及可能會出現狀態欄(Status Bar)以及輸入法窗口(Input Method Window),如圖1所示。架構
圖1 Activity窗口及其子窗口、壁紙窗口、輸入法窗口和狀態欄的位置結構框架
所以,WindowManagerService服務是不能夠假設同一時刻它只須要管理一個窗口的,它須要經過各個窗口在屏幕上的位置以及大小來決定哪些窗口須要顯示的以及要顯在哪裏,這實際上就是要計算出各個窗口的可見區域。ide
從前面Android系統Surface機制的SurfaceFlinger服務渲染應用程序UI的過程分析一文能夠知道,SurfaceFlinger服務在渲染整個屏幕的UI的時候,會對各個窗品的可見性進行計算,所以,WindowManagerService服務只要將它所管理的各個窗品的位置以及大小告訴SurfaceFlinger服務,後者能夠幫幫它計算出各個窗口的可見區域了。注意,這裏,這裏所說的窗口位置包括窗口在X、Y和Z軸的位置。函數
WindowManagerService服務大體按照如下方式來控制哪些窗口須要顯示的以及要顯在哪裏:學習
1. 每個Activity窗口的大小都等於屏幕的大小,所以,只要對每個Activity窗口設置一個不一樣的Z軸位置,而後就可使得位於最上面的,即當前被激活的Activity窗口,纔是可見的。動畫
2. 每個子窗口的Z軸位置都比它的父窗口大,可是大小要比父窗口小,這時候Activity窗口及其所彈出的子窗口均可以同時顯示出來。orm
3. 對於非全屏Activity窗口來講,它會在屏幕的上方留出一塊區域,用來顯示狀態欄。這塊留出來的區域稱對於屏幕來講,稱爲裝飾區(decoration),而對於Activity窗口來講,稱爲內容邊襯區(Content Inset)。blog
4. 輸入法窗口只有在須要的時候纔會出現,它一樣是出如今屏幕的裝飾區或者說Activity窗口的內容邊襯區的。接口
5. 對於壁紙窗口,它出現須要壁紙的Activity窗口的下方,這時候要求Activity窗口是半透明的,這樣就能夠將它後面的壁紙窗口一同顯示出來。
6. 兩個Activity窗口在切換過程,實際上就是前一個窗口顯示退出動畫然後一個窗口顯示開始動畫的過程,而在動畫的顯示過程,窗口的大小會有一個變化的過程,這樣就致使先後兩個Activity窗口的大小再也不都等於屏幕的大小,於是它們就有可能同時都處於可見的狀態。事實上,Activity窗口的切換過程是至關複雜的,由於即將要顯示的Activity窗口可能還會被設置一個啓動窗口(Starting Window)。一個被設置了啓動窗口的Activity窗口要等到它的啓動窗口顯示了以後才能夠顯示出來。
從以上六點就能夠看出,窗口在X、Y和Z軸的位置及其大小的計算很是重要,它們共同決定了一個窗口是不是總體可見的,仍是部分可見的,或者總體不可見的。在Android系統中,WindowManagerService服務是經過一個實現了WindowManagerPolicy接口的策略類來計算一個窗口的位置和大小的。例如,在Phone平臺上,這個策略類就是PhoneWindowManager。這樣作的好處就是對於不一樣的平臺實現不一樣的策略類來達到不一樣的窗口控制模式。
從上面的描述就能夠看出,WindowManagerService服務除了要與Activity窗口所運行在的應用程序進程打交道以外,還須要與SurfaceFlinger服務以及窗口管理策略類PhoneWindowManager交互,如圖2所示。
圖2 WindowManagerService服務與Activity窗口、SurfaceFlinger服務、PhoneWindowManager策略的關係圖
在前面Android應用程序窗口(Activity)實現框架簡要介紹和學習計劃的一系列文章中,咱們已經分析過應用程序進程與WindowManagerService服務之間的交互過程了,所以,在這一系列文章中,咱們就將主要分析WindowManagerService服務的實現,以及它與SurfaceFlinger服務、PhoneWindowManager策略類的交互過程。
從整體上來看,WindowManagerService服務的實現是至關複雜的,例如,WindowManagerService類的核心成員函數performLayoutAndPlaceSurfacesLockedInner的代碼有1200+行,比600-行代碼的ViewRoot類的核心成員函數performTraversals還要恐怖。不過,WindowManagerService服務實現的複雜性是在預料之中的,畢竟它要管理的整個系統全部窗口的UI,而在任何一個系統中,窗口管理子系統都是極其複雜的。基於上述理由,採用硬碰硬的方式來分析WindowManagerService服務的實現是以卵擊石,所以,這個系列的文章將對WindowManagerService服務進行分拆,而後再逐個擊破,這是算法中的分而治之思想是一致的。
具體來講,咱們將按照如下幾個情景來分析WindowManagerService服務的實現:
2. 窗口的組織方式。
3. 輸入法窗口的調整過程。
4. 壁紙窗口的調整過程。
5. 窗口Z軸位置的計算和調整過程。
7. Activity窗口的切換過程。
再次地,因爲WindowManagerService服務的實現實在是太複雜,所以上述八個情景可能還不足於說明WindowManagerService服務的實現。若是出現這種狀況,咱們在分析的過程當中會進行相應的調整。相信對WindowManagerService服務的實現進行分而治之的分析後,咱們就能夠對Android系統的UI架構有一個深入的理解!敬請關注接下來的文章!