天天看點

Android視窗管理(2)——消息傳遞

上一篇文章主要講述了視窗的基本結構,那麼在這樣的結構下,系統如何管理視窗,如何下發事件,如何擷取視窗狀态?這篇部落格将對這部分的内容進行介紹。

android在視窗管理上采用了最為經典的c/s模式,client端是各個activity中的window,而service端就是系統持有的視窗管理器window manager。

<code>window</code>是頂級的視窗概念,而<code>activity</code>中的<code>decorview</code>則是視窗中的頂級<code>view</code>,建立<code>activity</code>時,<code>decorview</code>會attach到<code>activity</code>的視窗中,同時也被加入到<code>windowmanager</code>中,<code>windowmanager</code>使用<code>windowstate</code>與該<code>view</code>相對應。

Android視窗管理(2)——消息傳遞

兩者之間通過建立session會話進行通信,而這裡的session采用的還是android中最重要的ipc方式——aidl。<code>activity</code>在建立視窗後需要将該視窗注冊到<code>windowmanager</code>中,這個過程涉及到在<code>activity</code>本地建立一個<code>windowmanager</code>的代理,<code>activity</code>通過這個代理和遠端<code>windowmanager</code>進行會話,會話的通道是<code>iwindowsession</code>,本質上就是一個aidl通信過程。

Android視窗管理(2)——消息傳遞

會話是雙向的,為了将消息發送給對應的<code>window</code>,<code>windowmanager</code>通過<code>iwindow</code>接口将對應的消息發送給<code>window</code>端對應的處理函數。

Android視窗管理(2)——消息傳遞

<code>activity</code>在建立的時候會調用<code>onattach()</code>建立<code>phonewindow</code>這個類,并在<code>handleresumeactivity</code>時将視窗加入到<code>windowmanager</code>中,不過加入的實際上并不是視窗,而是<code>decorview</code>。是以其實在用戶端的核心概念隻有<code>viewroot</code>,<code>decorview</code>以及<code>viewgroup</code>。其中後面兩者主要還是<code>view</code>的概念,真正完成與<code>windowmanager</code>進行通信的還是<code>viewroot</code>這個家夥。

<code>viewroot</code>的真正實作類是<code>viewrootimpl</code>。<code>viewroot</code>通過與<code>windowmanager</code>進行通信完成<code>addview</code>以及消息下發。

Android視窗管理(2)——消息傳遞

<code>viewroot</code>通過<code>iwindowsession</code>将視窗加入到<code>windowmanager</code>中。

Android視窗管理(2)——消息傳遞

<code>windowmanager</code>通過<code>iwindow</code>接口下發事件到<code>activity</code>。

是以<code>viewroot</code>其實本質上是一個<code>handler</code>,用于接收消息并處理消息。

<code>activity</code>利用<code>getsystemservice</code>來擷取<code>windowmanagerimpl</code>執行個體,而這個執行個體實際上就是<code>windowmanager</code>在用戶端本地的代理:

之後再調用<code>addview</code>接口通過<code>windowmanagerimpl</code>将視窗添加到<code>windowmanager</code>中。在<code>addview</code>的過程中,<code>windowmanagerimpl</code>會建立起<code>view</code>,<code>layout</code>,<code>viewroot</code>之間的對應關系,然後利用<code>iwindowsession</code>傳遞給<code>windowmanager</code>。

Android視窗管理(2)——消息傳遞

<code>windowmanager</code>是服務端管理視窗的元件,它管理的是各個應用的頂級視窗,也即<code>decorview</code>。将所有的視窗歸置到一個統一的系統服務<code>windowmanagerservice</code>管理是android系統的設計思想,這樣的機制并不難了解,系統總要有一個總管各個視窗的管家嘛,總不能任其自生自滅。<code>windowmanagerservice</code>的主要工作包括:

window service大體上實作了如下的功能:,

(1)z-ordered的維護函數 (2)輸入法管理 (3)addwindow/removewindow (4)layerout (5)token管理,apptoken (6)活動視窗管理(focuswindow) (7)活動應用管理(focusapp) (8)轉場動畫 (9)系統消息收集線程 (10)系統消息分發線程

在服務端視窗對象叫作<code>windowstate</code>,server端維護一個<code>mwindow</code>,其實就是一個按z-order排序的視窗數組。<code>mwindowmap</code>用于記錄<code>&lt;client:binder,windowstate對象&gt;</code>。

<code>windowstate</code>通過本地的<code>client</code>執行個體維護<code>iwindow</code>執行個體,同時利用該執行個體通路視窗。

原理其實很簡單,首先找到前台應用,然後根據<code>mwindow</code>找到z-order順序中第一位次的視窗,該視窗就是活動視窗。

token在本質上就是一個标示符,應用程式使用改标示符來找到該應用的視窗。<code>apptoken:&lt;token:ibinder,allwindows&gt;</code>。通過token就可以管理該應用的所有視窗。

下面再來說一下<code>windowmanager</code>的系統消息收集與分發過程。<code>windowmanagerservice</code>在内部維護了一個<code>keyq</code>的消息隊列,同時還有兩個線程:

1.inputdevicereader 2.inputdispatcherthread

<code>inputdevicereader</code>使用native函數<code>readevent</code>從driver中讀取<code>rawevent</code>并放到<code>keyq</code>隊列中。

<code>inputdispatherthread</code>負責從<code>keyq</code>隊列中讀取事件,并在<code>windowmanager</code>找到對應的視窗,利用該視窗的<code>iwindow</code>接口下發事件。

繼續閱讀