Github連接
本文梳理了Activity、View、Window、ViewRoot、Surface、AMS、WMS之間的關系,由于跳轉間的流程紛繁復雜,一旦陷入代碼細節(jié)就難以自拔,下文中分析省略掉很多細節(jié),想了解的可以閱讀源碼或者閱讀相對應的書籍。
概念定義
ContextImpl:Context實現(xiàn)類。
PhoneWindow:Window唯一實現(xiàn)類。Window是一個抽象概念,是添加到WindowManager的根容器。
ViewRootImpl:ViewRootImpl是View的根,它控制了View的測量和繪制,同時持有WindowSession通過Binder與WMS通信,同時持有IWindow作為WSM的回調(diào)接口,用于例如touch事件的回調(diào)。

WindowManagerImpl:WindowManager和ViewManager的實現(xiàn)類,通過WindowManagerGlobal與WMS通信。
DecorView:繼承FrameLayout,是視圖樹的根布局。

使用AS自帶的tools/layout inspector可以看出,整個DecorView包含了三部分:navigationBarBackground為導航欄,statusBarBackground為狀態(tài)欄,LinearLayout為當中內(nèi)容部分,展開LinearLayout.FrameLayout,可以得到action_bar_container即actionbar或toolbar和content(R.id.content)即真正setContentView的目標。
下文中但凡遇到抽象類/接口,都用實現(xiàn)類替代,而 -> 符號代表由函數(shù)跳轉到另一函數(shù)。
從啟動Activity說起
第一個部分是啟動Activity到創(chuàng)建出ViewRootImpl。

從ContextImpl開始,省略掉AMS里相關跳轉到最后ActivityThread.performLaunchActivity -> Activity.attach中創(chuàng)建出PhoneWindow。
繼續(xù)下一步調(diào)用方法 ActivityThread.handleResumeActivity -> WindowManagerImpl.addView創(chuàng)建出ViewRootImpl。

ViewRootImpl的構造方法內(nèi)創(chuàng)建了WindowSession(Binder),通過它與WindowManagerService進行通信。
小結:啟動Activity會創(chuàng)建ViewRootImpl和PhoneWindow,建立起與WMS的連接。
與WMS通信
第二步是ViewRootImpl與WMS通信。

接上第一步中在ViewRootImpl構造方法中通過WindowSession -> Binder.openSession構造出WindowSession。
由第一步7中WindowManagerImpl.addView -> … ->WMS.relayoutWindow根據(jù)Window測量的大小相對應創(chuàng)建出SurfaceControl,通過SurfaceControl.getSurface將測量結果寫入outSurface內(nèi),此處的outSurface就是ViewRootImpl.mSurface,注意此處只有大小,還未有指向native surface的指針mNativeObject。

由第一步7中WindowManagerImpl.addView -> … ->WindowState.attch,創(chuàng)建出WindowToken用來標識Window類型,如子窗體(1000-1999),應用窗體(1-99)和系統(tǒng)窗體(2000-2999)。再創(chuàng)建WindowState——WMS端的Window對象,它持有Session與WindowManager通信,更重要的是調(diào)用Session.windowAddedLocked創(chuàng)建出SurfaceSession。

SurfaceSession構造方法里調(diào)用了nativeCreate,從這里開始就是native的世界,不是本文重點,但簡單概括一下流程是通過創(chuàng)建SurfaceComposerClient與SurfaceFlinger進行交互,鎖定一塊共享內(nèi)存,通過writeParcel返回給ViewRootImpl.mSurface,同時擁有了native surface的地址。
小結:當Activity準備顯示時,會測量Window和添加Window,創(chuàng)建出WMS服務對應的WindowState,Surface和native Surface。
繪制
繪制四要素:bitmap(一塊內(nèi)存保存像素),canvas(畫布用于畫像素),paint(畫筆),path(畫的對象)。
應用無論是使用View/Canvas繪制(軟件繪制,Skia),或者使用硬件加速繪制,最底層都是與Surface(OpenGL)進行交互。
再回到Activity的生命周期onCreate,調(diào)用setContentView創(chuàng)建一個不可見的DecorView,當ActivityThread.handleResumeActivity -> Activity.makeVisible設置DecorView為可見。
其中繪制的起點是ViewRootImpl.performTraversals -> ViewRootImpl.performMeasure -> ViewRootImpl.performLayout - > ViewRootImpl.performDraw調(diào)用作為根視圖DecorView的measure,layout,draw方法來遍歷視圖樹。
值得一提的是FrameBuffer的知識點,開始繪制時,會調(diào)用Surface.lockCanvas,由SurfaceFlinger鎖定一塊共享內(nèi)存?zhèn)鬟f給Canvas,內(nèi)存共享的是設備顯存,在上面繪制相當于在屏幕上繪畫。繪制結束調(diào)用Surface.unlockCanvasAndPost,從Suface上detach掉canvas,釋放Surface。
觸類旁通之SurfaceView
SurfaceView會創(chuàng)建一個Z軸靠下的新Window,通過挖洞(重疊區(qū)域變透明)使自己可見。
觀察一下SurfaceView的內(nèi)部結構,似乎和ViewRootImpl差不多,同時持有IWindowSession,Surface和MyWindow(同ViewRootImple.WindowSession)

relayoutWindow,addWindow,Surface一氣呵成,流程比較簡單,注意一下SurfaceHolder,一般使用SurfaceView時候都是操作SurfaceHolder.Callback,它作為內(nèi)部類一開始就創(chuàng)建出來了,而在native surface創(chuàng)建完畢之后調(diào)用SurfaceHolder.Callback.surfaceCreated。

總結
Activity啟動時除了通過ViewRootImpl讀取各個參數(shù)確定Window的大小,位置等等,通過WMS創(chuàng)建出相應大小的Surface和一塊共享內(nèi)存,等待DecorView通過Canvas繪制畫面。
參考資料
Android 7.1.1 源碼
Android官方文檔
《Android開發(fā)藝術探索》
《深入理解Android 卷1》
其他優(yōu)秀的中英文文章