Android WMS(一)-窗口管理

原創(chuàng)內(nèi)容,轉(zhuǎn)載請(qǐng)注明出處,多謝配合。

WMS(WindowManagerService)是系統(tǒng)核心服務(wù),它職責(zé)主要包含如下幾個(gè)部分:

窗口管理和Surface管理,幾乎貫穿了之前圖形系統(tǒng)系列,這里相當(dāng)于單獨(dú)拎出來分析下,同時(shí)也是對(duì)之前圖形系統(tǒng)的知識(shí)點(diǎn)進(jìn)行回顧。本篇先針對(duì)窗口管理部分進(jìn)行梳理。

一、捋清幾個(gè)關(guān)系

關(guān)系1:Activity 、Window、View

這部分牽扯到的是窗口視圖架構(gòu)。

Activity是系統(tǒng)可視化交互組件,四大組件都由AMS統(tǒng)一管理生命周期,事實(shí)上它的職責(zé)只是生命周期的管理,由設(shè)計(jì)模式的單一職責(zé)的原則,那勢(shì)必需要將Activity和其上的視圖View進(jìn)行解耦,那么就引入Window的概念,它是個(gè)抽象類,對(duì)于Activity來說,它的具體實(shí)現(xiàn)類是PhoneWindow,在Activity執(zhí)行attach的時(shí)候,會(huì)創(chuàng)建一個(gè)PhoneWindow對(duì)象。PhoneWindow作為裝載根視圖DecorView的頂級(jí)容器,Activity通過setContentView實(shí)際上是調(diào)用PhoneWindow來創(chuàng)建DecorView,并解析xml布局加載到DecorView的contentView部分。

關(guān)系2:WindowManager、WindowManagerImpl、WindowManagerGlobal

這部分牽扯到的是應(yīng)用端的窗口管理架構(gòu)。

WindowManager是一個(gè)接口類,繼承自接口ViewManager,負(fù)責(zé)窗口的管理(增、刪、改)。它的實(shí)現(xiàn)類是WindowManagerImpl,而具體操作實(shí)際上又會(huì)交給WindowManagerGlobal來處理,它是個(gè)單例,進(jìn)程唯一。WindowManagerGlobal執(zhí)行addView的方法中會(huì)傳入DecorView, 還會(huì)初始化一個(gè)ViewRootImpl。WindowManagerGlobal因?yàn)槭菃卫?,它?nèi)部會(huì)有兩個(gè)List來分別保存這兩個(gè)對(duì)象,來統(tǒng)一管理。

關(guān)系3:ViewRootImpl、WindowManagerService

這份部分牽扯到的是具體窗口操作的binder IPC。

WindowManagerGlobal負(fù)責(zé)對(duì)DecorView和對(duì)應(yīng)的ViewRootImpl進(jìn)行統(tǒng)一管理,而具體功能是由ViewRootImpl來處理。

以addView為例,具體window是由WMS統(tǒng)一管理的,所以這里會(huì)進(jìn)行binder IPC。
binder IPC:
IWindowSession: 應(yīng)用程序通過Session與WMS通信,并且每個(gè)應(yīng)用程序進(jìn)程都會(huì)對(duì)應(yīng)一個(gè)Session。
IWindow: 作為WMS主動(dòng)與應(yīng)用程序通信的client端,因?yàn)椴煌腤indow是不同的client,因此它也被作為識(shí)別window的key。

具體可以參考之前圖形系統(tǒng)系列文章:
Android圖形系統(tǒng)(一)-Window加載視圖過程
Android圖形系統(tǒng)(二)-DecorView布局加載流程
Android圖形系統(tǒng)(三)-View繪制流程
Android圖形系統(tǒng)(四)-Activity、Window、View關(guān)系總結(jié)

二、Activity與Window關(guān)聯(lián)分析

Activity與Window聯(lián)系是非常緊密,很多顯示相關(guān)操作需要兩者密切配合,那么如何保證他們的一致性呢?Android通過token來保證兩者的一致性校驗(yàn):

token流向簡(jiǎn)單歸納如下:

1)new ActivityRecord的時(shí)候會(huì)new一個(gè)token與之對(duì)應(yīng)。

2)ApplicationThread scheduleLaunchActivity的時(shí)候,ActivityClientRecord 接收這個(gè)token。

3)activity.attach傳入該token。

4)setWindowManager的時(shí)候傳入該token,最終由Window的AppToken接收。

5)在WindowManagerGlobal的addView方法中,執(zhí)行adjustLayoutParamsForSubWindow,將WindowManager.LayoutParams wp,wp.token賦值appToken,并在之后的流程中,WindowManager.LayoutParams wp作為參數(shù)傳入WMS的addWindow方法對(duì)應(yīng)attrs.token。

6)WMS中通過WindowToken與之對(duì)應(yīng)。

那么其實(shí),Activity的token,Window中的token,連傳入addWindow的attrs.token,都是同一個(gè)token,都是ActivityRecord構(gòu)造函數(shù)中創(chuàng)建的Token對(duì)象。這樣做保證了一致性,主要體現(xiàn)在如下兩點(diǎn):

  • 將AMS中創(chuàng)建的ActivityRecord和Window掛鉤,當(dāng)前的window明確知道自己是哪一個(gè)Activity創(chuàng)建的。
  • Window和AMS有聯(lián)系,同時(shí)又和WMS有關(guān)系,appToken則保證了這種同步機(jī)制。

三、窗口屬性與類型

   WindowManagerGlobal的addView函數(shù)有個(gè)重要參數(shù):WindowManager.LayoutParams,它對(duì)應(yīng)有兩個(gè)重要的值:flag與type。

-flags:表示W(wǎng)indow的屬性:

flags 意義
FLAG_NOT_FOCUSABLE 表示W(wǎng)indow不需要獲取焦點(diǎn),也不需要接收各種輸入事件,此標(biāo)記會(huì)同時(shí)啟用FLAG_NOT_TOUCH_MODAL,最終事件會(huì)直接傳遞給下層具有焦點(diǎn)的Window。
FLAG_NOT_TOUCH_MODAL 系統(tǒng)會(huì)將當(dāng)前Window區(qū)域以外的單擊事件傳遞給底層的Window,當(dāng)前Window區(qū)域以內(nèi)的單擊事件則自己處理,這個(gè)標(biāo)記很重要,一般來說都需要開啟此標(biāo)記,否則其他Window將無法接收到單擊事件。
FLAG_SHOW_WHEN_LOCKED 開啟此模式可以讓W(xué)indow顯示在鎖屏的界面上。

-type: 表示窗口的類型(具體值太多了就不一一列舉了,具體可以去WindowManager的LayoutParams看詳細(xì)類型描述),窗口類型大體上就分三類:

window類型 特點(diǎn) 層級(jí)范圍 典型window代表
system window 獨(dú)立存在 2000~2999 Toast 、警告提示window、鍵盤window等
application window 屬于應(yīng)用的窗口 1~99 對(duì)應(yīng)的就是activity、dialog的window
sub window 需要依附于父window,不能獨(dú)立存在 1000~1999 popupWindow

四、窗口組織方式(分組與分層)

Android采用的是層疊式的布局

這個(gè)部分邏輯主要在WMS.addWindow中,這個(gè)方法非常非常重要!

分組
子窗口與其依附的父窗口屬于同一組,共用相同的token。

分層
WindowState在WMS中對(duì)應(yīng)一個(gè)具體的窗口。它有兩個(gè)重要屬性:

  • mBaseLayer:它按窗口類型來決定z-order順序。
  • mSubLayer:它按值的大小與正負(fù)關(guān)系來決定多個(gè)子窗口在父窗口中的前后關(guān)系,以及相互之間的順序。

然后,按如下流程來調(diào)整窗口的層級(jí)關(guān)系:

z-order計(jì)算過程

最終SurfaceFlinger會(huì)根據(jù)z-order順序來決定視圖的合成。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容