Android窗口治理機制

轉載一篇關於android window管理機制的文摘




Android 核心分析(13) -----Android GWES之Android窗口治理
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 
widgets, which are  used to create interactive UI components (buttons, text fields, etc.). The {@link android.view.ViewGroup} subclass is the base class  for layouts, 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用於記錄

WindowState有一個叫做mClient成員變量來記錄客戶端IWindow實例,通過IWindow接口實例,Service可以訪問客戶端的信息,說以IWindow是Service連接View橋樑。
(1) FocusWindow活動窗口如何計算?
基本原理就是查找前景應用(FousActivity),並同Z-Order序中找出屬於該FousActivity(AppToken)的主窗口,這個窗口就是計算出來的Focus Window。
(2)爲什麼要提出Token這個概念呢?
一個應用程序要管理自己的窗口,那麼如何來標識該窗口是屬於某個Activity,Andoid設計者提出了AppToken這個概念。AppToken在本質上的描述:
,通過Token找到屬於該Token的allWindows。使用Token開始完成該應用程序的所有窗口的顯示和隱藏。
(3)系統消息收集與處理
我們下面重點研究Service中的系統消息收集模式及其分發模式。Service使用KeyQ作爲專門的消息隊列。
KeyEvent
TouchEvent
TrackballEvent

系統有兩個線程:
KeyQ線程,通過Navite函數readEvent輪詢設備,將讀取的結果放置在KeyQ隊列中。
系統dispatcher 等待在KeyQ消息隊列上,一旦從消息隊列中獲取到消息,就通過分發函數通過mClient傳遞到Client端。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章