Window與WMS通信過程

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

轉載請注明出處:【huachao1001的簡書:http://www.lxweimin.com/users/0a7e42698e4b/latest_articles】

上一篇文章【理清Activity、View及Window之間關系】我們大致知道了Window的繪制過程,但是比較籠統,本文主要介紹Window對象與(后面縮寫為WMS)之間是如何通信。毫無疑問,肯定是通過IPCBinder機制),這點肯定都知道,但是我們要學習是的是,哪些類參與了IPC調用過程。另外,本文沒有研究源碼,而是通過閱讀其他研究源碼的文章,然后總結出來,以更容易理解的方式展示。本文設計到的相關資料在文章最后一一列出。

1 Window添加的大致過程

Window的添加過程需要通過WindowManageraddView來實現,WindowManager是一個接口,真正的實現是WindowManagerImpl。而WindowManagerImpl全部是轉移給WindowManagerGlobal來處理,WindowManagerImpl這種工作模式是典型的橋接模式。WindowManagerImpl內三大操作過程如下:

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,其內部維護如下幾個列表:

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所對應的View
  • mRoots:存儲的是所有Window所對應的ViewRootImpl
  • mParams:存儲的是所有Window所對應的布局參數
  • mDyingView:存儲了那些正在被刪除的View對象,或者說是那些已經調用了removeView方法但是刪除操作還未完成的Window對象。

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

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

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

可以看到,到目前為止,只是把相應的對象存放到ArrayList列表中。后面還需要將View給顯示出來。繪制View需要通過ViewRootImplsetView方法來實現。在setView內部是通過requestLayout來完成一部刷新請求的。

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

其中scheduleTraversalsView繪制的入口!

下面我們看看ViewRootImpl是內部機制。

2 ViewRootImpl內部機制

ViewRootImpl用于管理窗口的根View,并和WMS進行交互。ViewRootImpl中有一個內部類: W,以及另一個內部類:ViewRootHandler

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

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

ViewRootImpl有一個W類型的成員mWindowViewRootImpl在構造函數中創建一個W的實例并賦值給mWindow

ViewRootImplsetView方法(此方法運行在UI線程)中,會通過IPC的方式跨進程向WMS發起一個遠程調用,從而將DecorView最終添加到Window上,在這個過程中,ViewRootImplDecorViewWMS會彼此向關聯.

另外,WMS有時也需要向ViewRootImpl發送遠程請求,比如,點擊事件是由用戶的觸摸行為所產生的,因此它必須要通過硬件來捕獲,跟硬件之間的交互自然是Android系統自己把握,Android系統將點擊事件交給WMS來處理。WMS通過遠程調用將事件發送給ViewRootImpl,在ViewRootImpl中,有一個方法,叫做dispatchInputEvent,最終將事件傳遞給DecorView

3 Window與WMS之間的雙向通信

接下來,由WindowSession來完成最后的Window添加過程。mWindowSession本身是一個IWindowSession類型對象,通過內部代理類Proxy訪問遠程Session類(Binder機制) 。在Session內部通過WMS來實現Window的添加。如此一來Window的添加請求就交給了WMS去處理了,如下圖所示:

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

WindowManagerService內部為每個應用保留一個單獨的Session,如下圖所示:

每個應用對應一個Session

前面我們說過,每個Window對應一個ViewRootImpl及一個View Tree。也就是說,每個Activity對應的Window(一個或多個)內通過其內置的ViewRootImpl完成向WMS的請求過程。

一個應用中的所有Activity共用一個Session,一個WindowWMS內部對應一個WindowStateWindowState維護窗口的狀態以及根據適當的機制來調整窗口的狀態。

如果一個Activity多個Window,如對話框、Popup類型、或者通過ViewManagerView直接加入WMS,等等。在這些情況下,一個Activity就會創建多個Window,相應的WMS中也會對應多個WindowState,如下圖所示:

多個Window情況下對應關系

4 WMS控制窗口的顯示



以下內容來自老羅的的博客,后面附有資料鏈接。

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

  1. 每一個Activity窗口的大小都等于屏幕的大小,因此,只要對每一個Activity窗口設置一個不同的Z軸位置,然后就可以使得位于最上面的,即當前被激活的Activity窗口,才是可見的。

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

  3. 對于非全屏Activity窗口來說,它會在屏幕的上方留出一塊區域,用來顯示狀態欄。這塊留出來的區域稱對于屏幕來說,稱為裝飾區(decoration),而對于Activity窗口來說,稱為內容邊襯區(Content Inset)。

  4. 輸入法窗口只有在需要的時候才會出現,它同樣是出現在屏幕的裝飾區或者說Activity窗口的內容邊襯區的。

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

  6. 兩個Activity窗口在切換過程,實際上就是前一個窗口顯示退出動畫而后一個窗口顯示開始動畫的過程,而在動畫的顯示過程,窗口的大小會有一個變化的過程,這樣就導致前后兩個Activity窗口的大小不再都等于屏幕的大小,因而它們就有可能同時都處于可見的狀態。事實上,Activity窗口的切換過程是相當復雜的,因為即將要顯示的Activity窗口可能還會被設置一個啟動窗口(Starting Window)。一個被設置了啟動窗口的Activity窗口要等到它的啟動窗口顯示了之后才可以顯示出來。

參考資料:

  1. 【Android窗口管理服務WindowManagerService的簡要介紹和學習計劃 】
  2. 《Android開發藝術探索》
  3. 【Android 應用程序建立與WMS服務之間的通信過程】
  4. 【Android Window Manager Subsystem Research 】
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容