# Android GWES之Android窗口管理
### 1基本構架原理
Android的窗口管理是C/S模式的。Android中的Window是表示Top Level等頂級窗口的概念。DecorView是Window的Top-Level View,這個View我稱之為主View,DecorView會缺省的attach到Activity的主窗口中。主View被加入到WindowManager中,WM使用WindowState與這個主View對應。

Activity建立一個主窗口后,在將主窗口添加到WindowManager時,首先要建立WindowManager代理對象,并打開一個會話(實現IWindowSession AIDL接口),并維持該會話。Activity將通過該會話與WindowManager建立聯系,這個Session是C/S體系的基礎,Client通過WindowSession將window加入到Window Manager中。
一個完整的窗口概念橫跨了View,ViewRoot,WindowManager Service。Window,DecorView,View,IWindow ,ISession,WindowState之間的關系如下

Client端的Activity通過Session會話與WindowManager建立對話,而WindowManager則通過IWindow接口訪問Client,將消息傳遞到Client端,通過消息分發渠道,將消息傳遞到處理函數OnXXX。
后面我們將通過Client,WM Service分別加以分析。
### 2 Client端
我一致認為在Android中Window的概念并不是個很重要的概念。他的Window類,只是在PhoneWindow和MidWindow中使用。而PhoneWindow只是做了一個具體跟手機功能相關的公用事件的處理,所以在Android中PhoneWindow并不是一個抽象的純正概念,而是一個跟手機系統相關的一個特別窗口概念,例如按鍵的默認動作處理,按鍵音的發出等等。
##### 2.1 View
在Activity中真正重要的概念是View,以下是Google官方對View的定義:
This class represents the basic building block for user interface components. A View? occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for <em>widgets</em>, which are? used to create interactive UI components (buttons, text fields, etc.). The {@link android.view.ViewGroup} subclass is the base class? for <em>layouts</em>, which? are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.
我對View不做翻譯,翻譯成視圖好像不太佳,View在Android中,View比視圖具有廣的外延。View包含了用戶交互,包含了顯示,視圖在中文中僅僅表示了靜態的顯示。對于View的理解應該從最容易的理解開始。我們使用過編輯器,在Android中這個編輯器就是一個View,這個編輯器需要顯示文字,需要接收用戶的鍵盤輸入和鼠標選擇,但是一個屏幕上有多個編輯器,如何管理,如何切換焦點編輯器,這些都是需要管理的。
客戶端的組成:(Window,View,ViewRoot,WindowManager Proxy)

在Activity在performLaunchActivity時,會使用Activity.attach()建立一個PhoneWindow主窗口。這個主窗口的建立并不是一個重點。handleResumeActivity真正要啟動一個Activity時候,將主窗口加入到WindowManager,當然并不是將主窗口本身,而是將主窗口的DecorView加入到WindowManager中。
真正Window核心的抽象概念存在于View,ViewRoot,WindowManger中的WindowState。為了描述概念的方便性,我特別提出主View這個概念,這個主View就是Top-Level View of the window. 主View與View想對,突出主View是attatch到主窗口上的。而一般的View則是存在于主View中的。主窗口這個概念,我講的主窗口實際上就是Android提到的Top Level Window。
我們所提到的概念:View,GroupView,DecorView,ViewRoot都是存在于Client端,只有WindowState這個概念存在于Window Manager Service端。
DecorView實際上是一個ViewGroup。在依存關系上來講,對看個主窗口來講,DecorView是Top-Level View.View并不是關注的重點,重要的是我們如何需要知道分發路徑是建立在什么關系上的。View的成員變量mParent用來管理View上級關系的。而ViewGroup顧名思義就是一組View的管理,于是在ViewGroup構建了焦點管理和子View節點數組。這樣通過View的mParent和ViewGroup的mChildren構建了Android中View直接的關系網。

### 2.2 Focus Path
所謂的Foucs Path就是我們的KeyEvent傳遞的路線。一般的我們的KeyEvent在主循環中主View通過View的焦點記錄關系傳遞到焦點View上。例如下圖,View22是焦點,我們從最頂層的View通過mFcous的關系鏈找到最后所形成的路徑就是Focus Path。

### 2.3 ViewRoot,Window Manager Proxy
ViewRoot與Window Manager的核心是IWindowSession和IWindow。ViewRoot通過IWindowSession添加窗口到Window Manager。而IWindow這是Window Manager分發消息給Client ViewRoot的渠道。利用AIDL接口進行進程間通信。


ViewRoot實際是一個Handler,ViewRoot建立主View與WindowsManger通訊的橋梁。ViewRoot在本質上一個Handler。我們知道Handler的基本功能就是處理回調,發送消息。
Activity在使用getSystemService獲取WindowManagerImpl ,建立了一個WindowManagerImpl實例,即Window Manager服務的代理:
wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE);并調用wm.addview添加窗口到WMService中。
這個過程在客戶端建立了什么樣的管理框架,并如何這個會話?在Window Manager Proxy中建立了View,Layout ,ViewRoot三者的對應關系表。構造一個ViewRoot就會打開一個session,并利用IWindowSession建立會話上下文。

### 4 Window Manager Service
本次對于Window Manager Service的研究僅限于FocusWindow,消息系統。其他的部分將在后面的專門章節討論。??
Window Manager管理的窗口是應用程序的Top-level窗口,我這里參照Window的概念叫主窗口。主窗口為什么要放在在Service這邊來管理呢?為什么不放在Client那邊?主窗口放置在一起管理是為了計算Z-order序列,根據應用程序的狀態來顯隱應用程序的窗口。我想Android設計者在考慮設計窗口系統的時候,一定首先考慮:
- 窗口z-order序的管理
- 活動窗口的計算,及其變化通知
- 窗口歸屬(屬于哪個應用)
- 輸入法管理
Window Service大體上實現了如下的功能:,
(1)Z-ordered的維護函數
(2)輸入法管理
(3)AddWindow/RemoveWindow
(4)Layerout
(5)Token管理,AppToken
(6)活動窗口管理(FocusWindow)
(7)活動應用管理(FocusAPP)
(8)轉場動畫
(9)系統消息收集線程
(11)系統消息分發線程
在服務端的窗口對象叫做WindowState。在Service維護了一個mWindow數組,這個mWindow就是Window的Z-order序數組。mWindowMap用于記錄<Client:Binder,WindowState對象>。
WindowState有一個叫做mClient成員變量來記錄客戶端IWindow實例,通過IWindow接口實例,Service可以訪問客戶端的信息,說以IWindow是Service連接View橋梁。
(1) FocusWindow活動窗口如何計算?
基本原理就是查找前景應用(FousActivity),并同Z-Order序中找出屬于該FousActivity(AppToken)的主窗口,這個窗口就是計算出來的Focus Window。
(2)為什么要提出Token這個概念呢?
一個應用程序要管理自己的窗口,那么如何來標識該窗口是屬于某個Activity,Andoid設計者提出了AppToken這個概念。AppToken在本質上的描述:<Token:IBinder,allWindows>,通過Token找到屬于該Token的allWindows。使用Token開始完成該應用程序的所有窗口的顯示和隱藏。
(3)系統消息收集與處理
我們下面重點研究Service中的系統消息收集模式及其分發模式。Service使用KeyQ作為專門的消息隊列。
- KeyEvent
- TouchEvent
- TrackballEvent
系統有兩個線程:
KeyQ線程,通過Navite函數readEvent輪詢設備,將讀取的結果放置在KeyQ隊列中。
系統dispatcher 等待在KeyQ消息隊列上,一旦從消息隊列中獲取到消息,就通過分發函數通過mClient傳遞到Client端。
- 前言
- (一)分析方法論探討之設計意圖
- (二)方法論探討之概念空間篇
- (三)手機之硬件形態
- (四)手機的軟件形態
- (五)基本空間劃分
- (六)IPC框架分析 Binder,Service,Service manager
- (七)Service深入分析
- (八)Android 啟動過程詳解
- (九)Zygote Service
- (十)Android GWES之基本原理篇
- (十一)Android GWES之消息系統
- (十二)Android GEWS窗口管理之基本架構原理
- (十三)Android GWES之Android窗口管理
- (十四)Android GWES之輸入系統
- (十五)Android輸入系統之輸入路徑詳解
- (十六)Android電話系統-概述篇
- (十七)電話系統之rilD
- (十八)Android電話系統之RIL-Java
- (十九)電話系統之GSMCallTacker
- (二十)Android應用程序框架之無邊界設計意圖
- (二十一)Android應用框架之AndroidApplication
- (二十二)Android應用框架之Activity
- (二十三)Andoird GDI之基本原理及其總體框架
- (二十四)Android GDI之顯示緩沖管理
- (二十五)Android GDI之共享緩沖區機制
- (二十六)Android GDI之SurfaceFlinger
- (二十七)Android GDI 之SurfaceFlinger之動態結構示意圖
- (二十八)Android GDI之Surface&amp;Canvas