本文是Android視圖層源碼分析系列第4篇文章,主要是對前幾篇文章作一個總結,理解Android視圖的主要組成部分和相互之間的工做邏輯。本文內容是基於Google Android Repo中的較新的源碼分析而得來的。java
這張圖大體解釋了各模塊之間的關係:android
下文內容並無具體的分析邏輯,主要是解釋上圖中各模塊的職責,算是對Android視圖層各模塊的一個小總結,方便對於整個AndroidUI顯示原理的理解。git
Window
能夠說是Android Framework
層提供的一個最基礎的UI
組件管理類,PhoneWindow
是它的惟一實現類。它屏蔽了開發者與WindowManagerService
的交互,統一了UI設計,並統一接收用戶交互事件,好比背景、title和按鍵事件等。github
Activity/Dialog/Toast
的UI展示都是依賴於Window
來完成。對於UI編寫,開發者只須要使用View
相關便可。View
最終會以ContentView
的形式設置給Window
:bash
PhoneWindow.java微信
public void setContentView(int layoutResID) {
}
複製代碼
DecorView
是PhoneWindow
的根ViewGroup
。Window
提供了一些列的配置項,不一樣的配置項DecorView
的UI組成會有必定的不一樣。關於Window
的具體組成能夠參考前面深刻剖析Window組成一文。源碼分析
一個Window
會有一個WindowManager
。提到WindowManager
就要提到WindowManagerGlobal
。他們之間的區別是:佈局
Window
,並提供一系列對Window
進行配置的flag。Window
(其實並非很嚴謹,應該是管理全部的ViewRootImpl
)。而且它含有與WindowManagerService
通訊的Binder
。WindowManager
所提供的API其實都是用來操做WindowManagerGlobal
中的ViewRootImpl
。好比WindowManager.addView(contentView)
其實是在WindowManagerGlobal
中建立了一個與contentView
對應的ViewRootImpl
。post
它負責管理一個具體的View Tree
,好比DecorView
及其全部子View。具體有下面這些職責:動畫
WindowManagerService
通訊,建立Surface
來顯示其管理的View Tree
View Tree
的測量、佈局、繪製。具體方法是performTraversals
Choreographer
來使整個ViewTree
的UI刷新(測量、佈局、繪製)與系統同步。Choreographer
用來控制同步處理輸入(Input)、動畫(Animation)、繪製(Draw)三個UI操做(UI顯示的時候每一幀要完成的事情只有這三種)。其內部維護着一個Queue
,使用者能夠經過postXXX
來把一些列待運行的UI操做放到Queue
中。這些事件會在Choreographer
接收顯示系統的時間脈衝(垂直同步信號-VSync信號)後執行這些操做。好比ViewRootImpl
對於View Tree
的更新事件:
ViewRootImpl.java
void scheduleTraversals() {
...
mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
}
複製代碼
一個ViewRootImpl
含有一個Surface
(一個Surface
含有一個Canvas
)。能夠把它理解爲一個畫布,經過Canvas
能夠在上面做畫。ViewRootImpl
的整個ViewTree
是draw
在Surface
上的。
它實際上對應的是SurfaceFlinger
中的Layer
,在Surface
上繪製的內容最終會由SurfaceFlinger
來渲染。
它管理着全部應用程序的Window
:
Window
的狀態(WindowState)SurfaceFlinger
通訊,完成Window
的渲染經過ViewRootImpl
能夠向WindowManagerService
添加一個Window
:
ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
//mWindow是一個`Binder`
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
...
}
複製代碼
mWindowSession
是IWindowSession
的實例,是一個與WindowManagerService
通訊的Binder
。由WindowManagerGlobal
建立和維護,一個應用程序只會有一個。
WindowState
用於在WindowManagerService
中表明一個Window
,它含有一個窗口的全部屬性,它和ViewRootImpl
是對應的。它被保存在WindowManagerService
的mWindowMap
集合中。mWindowMap
是整個系統全部窗口的一個全集。
WindowToken
將屬於同一個應用程序組件的窗口組織在一塊兒。在WindowManagerService
對窗口管理的過程當中,用WindowToken
表明一個應用組件。例如在進行窗口Z-Order排序時,屬於同一個WindowToken
的窗口(Window
)會被安排在一塊兒,也能夠理解爲渲染Window的Surface
的Z軸順序。一個token下能夠有多個WindowState(Window)
:
WindowManagerService.addWindow()
win.mToken.addWindow(win);//一個token下會有多個win state
複製代碼
SurfaceFlinger
是Android最重要的系統服務之一,它主要負責UI
的渲染,具體能夠說是Layer
的合成和渲染。下面介紹的幾個對象基本都是存在於WindowManagerService
中的。是應用程序與SurfaceFlinger
交互的關鍵對象。
能夠簡單的把它理解爲Surface
的管理者。它和Surface
是一對一的關係。構建SurfaceControl
的同時就會構造Surface
。ViewRootImpl
的Surface
實際上和它指向的是同一個對象。它能夠經過SurfaceComposerClient
來與SurfaceFlinger
通訊。好比請求SurfaceFlinger
建立Surface(Layer)
這個對象也是進程惟一的,一個應用只有一個。能夠經過它與SurfaceFlinger
創建鏈接,從而與SurfaceFlinger
通訊。具體通訊的功能是由Client
對象來完成的。
它是一個Binder
,SurfaceComposerClient
能夠經過它來與SurfaceFlinger
通訊。好比經過它可使SurfaceFlinger
建立一個Layer
。它也維護着一個應用程序全部的Layer
。
被SurfaceFlinger
管理着,分爲多種不一樣的類型。它是一個可被SurfaceFlinger
渲染的單元。它有一個BufferQueueProducer
,裏面維護着不少能夠被渲染的GraphicBuffer
,這個buffer可能被渲染完畢,也可能處於待渲染狀態。
想詳細瞭解上面知識,閱讀源碼是權威的辦法,也能夠參考下面這些文章來理清思路:
一篇文章看明白 Android 圖形系統 Surface 與 SurfaceFlinger 之間的關係
[深刻理解Android]系列從書
後面會繼續從總體上了解Android視圖層的事件處理。
最後:
歡迎關注個人Android進階計劃看更多幹貨
歡迎關注個人微信公衆號:susion隨心