android視窗管理剖析
一、 概述
在Android系統中,從設計的角度來看,視窗管理系統是基於C/S模式的。整個視窗系統分為服務端和客戶端兩大部分,客戶端負責請求建立視窗和使用視窗,服務端完成視窗的維護,視窗顯示等。
在Client端,並不是直接和 WindowManagerService互動,而是直接和本地物件WindowManager互動,然後由WindowManager完成和 WindowManagerService的互動。對於Android應用來說這個互動是透明的,應用不能感知到 WindowManagerService的存在
二、 視窗的定義
在android的應用框架中,視窗主要分為兩種:
第一種是應用視窗:一個activity有一個主視窗,彈出的對話方塊 也有一個視窗,Menu選單也是一個視窗。在同一個activity中,主視窗、對話方塊、Menu視窗之間通過該activity關聯起來。和應用相關的 視窗表示類是PhoneWindow和Window,PhoneWindow繼承於Window,針對手機螢幕做了一些優化工作。PhoneWindow 只是一個視窗封裝類,裡面核心的是mDecorView這個變數,mDecorView是一個頂層的View,視窗的新增就是通過呼叫 getDecorView()獲取到mDecorView並且呼叫WindowManager.addView()把該View新增到 WindowManager中。
第二種是公共介面的視窗:如最近執行對話方塊、關機對話方塊、狀態列下拉 欄、鎖屏介面等。這些視窗都是系統級別的視窗,不從屬於任何應用,和activity沒有任何關係。這種視窗沒有任何視窗類來封裝,直接呼叫 WindowManager.addView()來把一個view新增到WindowManager中。
在應用初始化的時候,會首先生成一個Activity物件,此時該 activity還沒有屬於他的一個視窗。緊接著通過呼叫attach()函式,在attach()函式裡面該activity會呼叫 PolicyManager.makeNewWindow()建立一個新的PhoneWindow,然後在activity的onCreate()生命周 期裡,一般應用都會呼叫setContentView()設定該activity的顯示介面。在setContentView()裡,框架會自動生成一個 佈局,該佈局檔案包含了如標題欄、ActionBar等元素,最重要的是包含了應用的contentView。這個佈局對應的就是PhoneWindow 裡面的mDecorView。最後在activity將要顯示出來之前,通過getWindow().getDecorView()獲取到 DecorView,並通過WindowManager.addView()把DecorView新增到WindowManager中。
Activity新增客戶端視窗時序圖
三、 視窗管理
Android的窗關管理是基於C/S模式的,並且使用獨立程式的方 式實現。視窗管理的服務端WindowManagerService執行在獨立的程式system_server裡,當應用程式需要建立視窗時,通過程式 通訊的方式請求WindowManagerService建立視窗,由WindowManagerService嚮應用程式傳遞和視窗相關的互動訊息。所 有程式的視窗都在服務端管理,視窗的顯示和控制都在WindowManagerService裡處理。
WindowManagerService主要完成了以下幾部分功能:
1. 視窗的新增和刪除
2. 視窗的顯示和隱藏控制
3. Z-order順序管理
4. 焦點視窗和焦點應用的管理
5. 輸入法視窗管理和牆紙視窗管理
6. 轉場動畫
7. 系統訊息收集和分發
服務端的實現程式碼是在/framework/base/services/java/com/android/server/wm/裡,核心的幾個類是:
WindowManagerService.java
WindowState.java
WindowToken.java
AppWindowToken.java
Session.java
InputManager.java
InputMonitor.java
類解釋:
WindowManagerService負責完成視窗的管理工作;
WindowState和客戶端視窗一一對應,應用呼叫WindowManager.addView()時,最終會在WindowManagerService新增一個WindowState與之一一對應。
WindowToken是一個控制程式碼,儲存了所有具有同一個token 的WindowState。應用請求WindowManagerService新增視窗的時候,提供了一個token,該token標識了被新增視窗的歸 屬,WindowManagerService為該token生成一個WindowToken物件,所有token相同的WindowState被關聯到 同一個WindowToken。如輸入法新增視窗時,會傳遞一個mCurrToken,牆紙服務新增視窗時,會傳遞一個newConn.mToken。
AppWindowToken繼承於WindowToken,專門用 於標識一個Activity。AppWindowToken裡的token實際上就是指向了一個Activity。 ActivityManagerService通知應用啟動的時候,在服務端生成一個token用於標識該Activity,並且把該token傳遞到應 用客戶端,客戶端的Activity在申請新增視窗時,以該token作為標識傳遞到WindowManagerService。同一個Activity 中的主視窗、對話方塊視窗、選單視窗都關聯到同一個AppWindowToken。
Session表示一個客戶端和服務端的互動會話。一般來說不同的應用通過不同的會話來和WindowManagerService互動,但是處於同一個程式的不同應用通過同一個Session來互動。
InputManager和InputMonitor負責上層的訊息分發功能。
WindowManagerService內部的幾個重要成員變數:
ArrayList<WindowState> mWindows
HashMap<IBinder, WindowState> mWindowMap
ArrayList<WindowToken> mTokenList
ArrayList<AppWindowToken> mAppTokens
mWindows儲存了系統中所有的WindowState;
mWindowMap儲存了每個WindowState和客戶端視窗的對映關係,客戶端應用請求視窗操作時,通過mWindowMap查詢到對應的WindowState;
mTokenList儲存了所有的WindowToken
mAppTokens儲存了所有的AppWindowToken
視窗管理服務端主要類圖
一個Activity從啟動到新增視窗的整個流程如下:
ActivityManagerService在接收到啟動 Activity請求時,首先生成一個token作為該Activity的唯一標識。然後呼叫WindowManagerService向其新增一個 AppWindowToken,此AppWindowToken封裝了Activity的token。接著AMS啟動應用客戶端程式並把token傳遞到 該程式,在客戶端程式裡完成Activity的初始化。在Activity的attach()函式中,Activity完成PhoneWindow的創 建,並且把token傳遞給PhoneWindow。在Activity呼叫WindowManager.addView()時,在 WindowManager內部會把token和該View關聯,真正向WindowManagerService申請建立視窗的時候,再把token傳 遞給WindowManagerService。WindowManagerService接收到建立視窗的請求的時候,通過mTokenMap查詢對應 該token的AppWindowToken,如果為空則丟擲異常,否則建立一個WindowState並完成初始化工作和其他資料結構的調整工作。在這 個過程中,token貫穿了服務端的AMS、WMS和客戶端的Activity、Window。
Activity啟動過程中建立視窗的時序圖
四、 WMS中服務端和客戶端的互動介面和資料結構
應用請求建立視窗時,和應用直接互動的是WindowManager 物件。WindowManager只是一個介面,呼叫addView()建立視窗時正真互動的是WindowManagerImpl物件。 WindowManagerImpl管理單個應用的所有本地視窗。應用呼叫addView()建立視窗時,WindowManagerImpl會生成一個 ViewRoot物件與之相對應,並且把相應的引數LayoutParams儲存起來。
addView()的執行流程如下:
(1) 檢查所新增的視窗是否已經新增過,不允許重複新增;
(2) 如果所新增視窗為子視窗型別,找到其父視窗,並儲存在內部變數中;
(3) 建立一個新的ViewRoot,並儲存對應的View(DecorView)和LayoutParams;
(4) 呼叫ViewRoot的setView()方法,完成真正意義上的新增工作。
ViewRoot本質上是一個Handler,並且實現了ViewParent介面。ViewRoot的主要功能是:
1. 負責分發訊息事件,如Key、Motion事件等;
2. 負責和WMS的互動,分發WMS的互動命令;
3. 作為DecorView的parent,對DecorView進行draw、measure、layout等操作;
在addView()的第3、4步完成之後,ViewRoot就全權接管了和WMS的互動工作,DecorView不需要做任何互動動作。ViewRoot和WMS之間的雙向對話,主要是通過以下兩個資料結構進行的:
IWindowSession
IWindow
這兩個資料結構都是標準的aidl介面,用於程式之間的同步通訊。 IWindowSession負責ViewRoot到WMS的單向請求,IWindow則用於WMS回撥ViewRoot。在ViewRoot物件內部, 存在著一個IWindowSession的靜態成員和一個IWindow的非靜態成員,所以一個程式裡只有一個IWindowSession物件,但是可 以有多個IWindow物件。
Window、WindowManager、DecorView、ViewRoot、IWindowSession、IWindowSession、WindowState、WindowManagerService之間的關係可用下圖來表示:
在ViewRoot的建構函式中,呼叫 getWindowSession()初始化靜態成員sWindowSession和非靜態成員mWindow。在第4步呼叫setView()方法 時,ViewRoot會呼叫sWindowSession.add()方法,把IWindow新增到WMS中,WMS就會生成一個WindowState 與之一一對應,並且把IWindow物件儲存到WindowState內部作為回撥的介面。之後所有WMS的命令,都會通過直接訪問IWindow介面, 以訊息的形式分發到ViewRoot,ViewRoot來完成相應的處理,或對DecorView進行操作,或完成後通過sWindowSession報 告給WMS。
一個視窗從新增到顯示可用以下時序圖表示:
視窗新增過程時序圖
轉自:http://www.voidcn.com/blog/huanxido/article/p-3139816.html
相關文章
- Android視窗管理分析(2):WindowManagerService視窗管理之Window新增流程Android
- Android 之 Window、WindowManager 與視窗管理Android
- Android視窗管理分析(3):視窗分組及Z-order的確定Android
- Android 8.0 原始碼分析 (十) WindowManagerService 的視窗管理Android原始碼
- android的視窗機制分析------UI管理系統AndroidUI
- Android顯示框架:Android應用視窗的管理者WindowManagerAndroid框架
- 圖解Android - Android GUI 系統 (2) - 視窗管理 (View, Canvas, Window Manager)圖解AndroidGUIViewCanvas
- Android 7.0 多視窗模式Android模式
- Qt 佈局管理 - 停靠視窗QT
- Android 多視窗程式設計Android程式設計
- Android 視窗是如何建立的?Android
- macos視窗管理器:Lasso for MacMac
- Rectangle for Mac視窗管理工具Mac
- Mac 多螢幕視窗管理神器Mac
- 視窗管理器 xmonad 教程
- Android視窗管理分析(4):Android View繪製記憶體的分配、傳遞、使用AndroidView記憶體
- Android N新特性--多視窗支援Android
- Android 懸浮視窗的實現Android
- Android的左滑關閉視窗Android
- 蘋果視窗管理工具:Moom for Mac蘋果OOMMac
- Mac雙視窗檔案管理:MaxCommanderMac
- Moom for Mac(蘋果視窗管理工具)OOMMac蘋果
- android的視窗機制分析------ViewRoot類AndroidView
- Cisdem Window Manager for Mac 視窗管理工具Mac
- Display Maid for Mac視窗管理工具AIMac
- macOS視窗管理軟體Magnet最新中文Mac
- IDEA 開啟 services視窗 管理微服務Idea微服務
- Hiddex -視窗管理工具簡介
- Android視窗管理分析(1):View如何繪製到螢幕上的主觀理解AndroidView
- JavaScript - 模式視窗和非模式視窗JavaScript模式
- Android應用視窗突破手機侷限性Android
- Android 7.0中的多視窗實現解析Android
- android的視窗機制分析------事件處理Android事件
- Android通用業務彈窗管理方案PopLayerV1Android
- Android通用業務彈窗管理方案PopLayerV2Android
- 01-Tkinter教程-視窗的管理與設定
- 視窗管理工具:All Windows Appear for MacWindowsAPPMac
- 雙視窗檔案管理器Commander One