Window與WMS通信過程

我的CSDN博客同步發(fā)布:Window與WMS通信過程

轉(zhuǎn)載請注明出處:【huachao1001的簡書:http://www.reibang.com/users/0a7e42698e4b/latest_articles】

上一篇文章【理清Activity藻烤、View及Window之間關(guān)系】我們大致知道了Window的繪制過程或辖,但是比較籠統(tǒng),本文主要介紹Window對象與(后面縮寫為WMS)之間是如何通信怀伦。毫無疑問帅容,肯定是通過IPCBinder機(jī)制)装畅,這點(diǎn)肯定都知道晶衷,但是我們要學(xué)習(xí)是的是,哪些類參與了IPC調(diào)用過程抄邀。另外耘眨,本文沒有研究源碼,而是通過閱讀其他研究源碼的文章境肾,然后總結(jié)出來剔难,以更容易理解的方式展示。本文設(shè)計(jì)到的相關(guān)資料在文章最后一一列出奥喻。

1 Window添加的大致過程

Window的添加過程需要通過WindowManageraddView來實(shí)現(xiàn)偶宫,WindowManager是一個接口,真正的實(shí)現(xiàn)是WindowManagerImpl衫嵌。而WindowManagerImpl全部是轉(zhuǎn)移給WindowManagerGlobal來處理读宙,WindowManagerImpl這種工作模式是典型的橋接模式彻秆。WindowManagerImpl內(nèi)三大操作過程如下:

public void addView(View view,ViewGroup.LayoutParams params){
    mGlobal.addView(view,params,mDisplay,mParantWindow);
}

public void updateViewLayout(View view,ViewGroup.LayoutParams params){
    mGlobal.updateViewLayout(view,params);
}

public void removeView(View view){
    mGlobal.removeView(view,false);
}

WindowManagerGlobal名稱可以看出楔绞,它是一個全局的WindowManager,其內(nèi)部維護(hù)如下幾個列表:

private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>()
private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.layoutParams>();
private final ArraySet<View> mDyingViews = new ArraySet<View>();

其中:

  • mViews:存儲所有Window所對應(yīng)的View
  • mRoots:存儲的是所有Window所對應(yīng)的ViewRootImpl
  • mParams:存儲的是所有Window所對應(yīng)的布局參數(shù)
  • mDyingView:存儲了那些正在被刪除的View對象唇兑,或者說是那些已經(jīng)調(diào)用了removeView方法但是刪除操作還未完成的Window對象酒朵。

addView中通過如下方式將Window的一系列對象添加到列表中:

root=new ViewRootImpl(view.getContext(),display);
view.setLayoutParams(wparams);

mViews.add(view);
mRoots.add(root);
mParams.add(wparams);

可以看到,到目前為止扎附,只是把相應(yīng)的對象存放到ArrayList列表中蔫耽。后面還需要將View給顯示出來。繪制View需要通過ViewRootImplsetView方法來實(shí)現(xiàn)。在setView內(nèi)部是通過requestLayout來完成一部刷新請求的匙铡。

public void requestLayout(){
    if(!mHandlingLayoutInlayoutRequest){
        checkThread();
        mLayoutRequested=true;
        scheduleTraversals();
    }
}

其中scheduleTraversalsView繪制的入口图甜!

下面我們看看ViewRootImpl是內(nèi)部機(jī)制。

2 ViewRootImpl內(nèi)部機(jī)制

ViewRootImpl用于管理窗口的根View鳖眼,并和WMS進(jìn)行交互黑毅。ViewRootImpl中有一個內(nèi)部類: W,以及另一個內(nèi)部類:ViewRootHandler钦讳。

  • W繼承自IWindow.Stub矿瘦。是一個Binder對象,用于接收WMS的各種消息愿卒, 如按鍵消息缚去, 觸摸消息等。

  • ViewRootHandler琼开,是Handler的子類易结, W會通過Looper把消息傳遞給ViewRootHandler

ViewRootImpl有一個W類型的成員mWindow稠通,ViewRootImpl在構(gòu)造函數(shù)中創(chuàng)建一個W的實(shí)例并賦值給mWindow衬衬。

ViewRootImplsetView方法(此方法運(yùn)行在UI線程)中,會通過IPC的方式跨進(jìn)程向WMS發(fā)起一個遠(yuǎn)程調(diào)用改橘,從而將DecorView最終添加到Window上滋尉,在這個過程中,ViewRootImpl飞主、DecorViewWMS會彼此向關(guān)聯(lián).

另外狮惜,WMS有時也需要向ViewRootImpl發(fā)送遠(yuǎn)程請求,比如碌识,點(diǎn)擊事件是由用戶的觸摸行為所產(chǎn)生的碾篡,因此它必須要通過硬件來捕獲,跟硬件之間的交互自然是Android系統(tǒng)自己把握筏餐,Android系統(tǒng)將點(diǎn)擊事件交給WMS來處理开泽。WMS通過遠(yuǎn)程調(diào)用將事件發(fā)送給ViewRootImpl,在ViewRootImpl中魁瞪,有一個方法穆律,叫做dispatchInputEvent,最終將事件傳遞給DecorView导俘。

3 Window與WMS之間的雙向通信

接下來峦耘,由WindowSession來完成最后的Window添加過程。mWindowSession本身是一個IWindowSession類型對象旅薄,通過內(nèi)部代理類Proxy訪問遠(yuǎn)程Session類(Binder機(jī)制) 辅髓。在Session內(nèi)部通過WMS來實(shí)現(xiàn)Window的添加。如此一來Window的添加請求就交給了WMS去處理了,如下圖所示:

ViewRootImpl與WmS之間通信
ViewRootImpl與WmS之間通信

WindowManagerService內(nèi)部為每個應(yīng)用保留一個單獨(dú)的Session洛口,如下圖所示:

每個應(yīng)用對應(yīng)一個Session

前面我們說過矫付,每個Window對應(yīng)一個ViewRootImpl及一個View Tree。也就是說第焰,每個Activity對應(yīng)的Window(一個或多個)內(nèi)通過其內(nèi)置的ViewRootImpl完成向WMS的請求過程技即。

一個應(yīng)用中的所有Activity共用一個Session,一個WindowWMS內(nèi)部對應(yīng)一個WindowState樟遣,WindowState維護(hù)窗口的狀態(tài)以及根據(jù)適當(dāng)?shù)臋C(jī)制來調(diào)整窗口的狀態(tài)而叼。

如果一個Activity多個Window,如對話框豹悬、Popup類型葵陵、或者通過ViewManagerView直接加入WMS,等等瞻佛。在這些情況下脱篙,一個Activity就會創(chuàng)建多個Window,相應(yīng)的WMS中也會對應(yīng)多個WindowState伤柄,如下圖所示:

多個Window情況下對應(yīng)關(guān)系

4 WMS控制窗口的顯示



以下內(nèi)容來自老羅的的博客绊困,后面附有資料鏈接。

WMS服務(wù)大致按照以下方式來控制哪些窗口需要顯示的以及要顯在哪里:

  1. 每一個Activity窗口的大小都等于屏幕的大小适刀,因此秤朗,只要對每一個Activity窗口設(shè)置一個不同的Z軸位置,然后就可以使得位于最上面的笔喉,即當(dāng)前被激活的Activity窗口取视,才是可見的。

  2. 每一個子窗口的Z軸位置都比它的父窗口大常挚,但是大小要比父窗口小作谭,這時候Activity窗口及其所彈出的子窗口都可以同時顯示出來。

  3. 對于非全屏Activity窗口來說奄毡,它會在屏幕的上方留出一塊區(qū)域折欠,用來顯示狀態(tài)欄。這塊留出來的區(qū)域稱對于屏幕來說吼过,稱為裝飾區(qū)(decoration)锐秦,而對于Activity窗口來說,稱為內(nèi)容邊襯區(qū)(Content Inset)那先。

  4. 輸入法窗口只有在需要的時候才會出現(xiàn)农猬,它同樣是出現(xiàn)在屏幕的裝飾區(qū)或者說Activity窗口的內(nèi)容邊襯區(qū)的赡艰。

  5. 對于壁紙窗口售淡,它出現(xiàn)需要壁紙的Activity窗口的下方,這時候要求Activity窗口是半透明的,這樣就可以將它后面的壁紙窗口一同顯示出來揖闸。

  6. 兩個Activity窗口在切換過程揍堕,實(shí)際上就是前一個窗口顯示退出動畫而后一個窗口顯示開始動畫的過程,而在動畫的顯示過程汤纸,窗口的大小會有一個變化的過程衩茸,這樣就導(dǎo)致前后兩個Activity窗口的大小不再都等于屏幕的大小,因而它們就有可能同時都處于可見的狀態(tài)贮泞。事實(shí)上楞慈,Activity窗口的切換過程是相當(dāng)復(fù)雜的,因?yàn)榧磳⒁@示的Activity窗口可能還會被設(shè)置一個啟動窗口(Starting Window)啃擦。一個被設(shè)置了啟動窗口的Activity窗口要等到它的啟動窗口顯示了之后才可以顯示出來囊蓝。

參考資料:

  1. 【Android窗口管理服務(wù)WindowManagerService的簡要介紹和學(xué)習(xí)計(jì)劃 】
  2. 《Android開發(fā)藝術(shù)探索》
  3. 【Android 應(yīng)用程序建立與WMS服務(wù)之間的通信過程】
  4. 【Android Window Manager Subsystem Research 】
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市令蛉,隨后出現(xiàn)的幾起案子聚霜,更是在濱河造成了極大的恐慌,老刑警劉巖珠叔,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝎宇,死亡現(xiàn)場離奇詭異,居然都是意外死亡祷安,警方通過查閱死者的電腦和手機(jī)姥芥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汇鞭,“玉大人撇眯,你說我怎么就攤上這事∈郑” “怎么了熊榛?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長腕巡。 經(jīng)常有香客問我玄坦,道長,這世上最難降的妖魔是什么绘沉? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任煎楣,我火速辦了婚禮,結(jié)果婚禮上车伞,老公的妹妹穿的比我還像新娘择懂。我一直安慰自己,他們只是感情好另玖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布困曙。 她就那樣靜靜地躺著表伦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慷丽。 梳的紋絲不亂的頭發(fā)上蹦哼,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機(jī)與錄音要糊,去河邊找鬼纲熏。 笑死,一個胖子當(dāng)著我的面吹牛锄俄,可吹牛的內(nèi)容都是我干的局劲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼奶赠,長吁一口氣:“原來是場噩夢啊……” “哼容握!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起车柠,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤剔氏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后竹祷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谈跛,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年塑陵,在試婚紗的時候發(fā)現(xiàn)自己被綠了感憾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡令花,死狀恐怖阻桅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兼都,我是刑警寧澤嫂沉,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站扮碧,受9級特大地震影響趟章,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜慎王,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一蚓土、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赖淤,春花似錦蜀漆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绷耍。三九已至,卻和暖如春蠕嫁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背毯盈。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工剃毒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搂赋。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓赘阀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脑奠。 傳聞我的和親對象是個殘疾皇子基公,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容