前言
本文本來是自己覆盤 Android 知識梳理用的,沒想到在上週部門內部的知識測評中發現,同事們對這些基礎知識的掌握參差不齊,甚至可以說是模棱兩可。
是網上關於 Activity 的教程太少了嗎?不是的,恰恰相反,網上的信息多如牛毛,卻沒有一篇願意費哪怕一絲絲的筆墨 來介紹 Activity 的起源、它的職責邊界、它的存在到底是爲了解決什麼問題、我們學習它,到底學到什麼程度纔算掌握。
正因爲對這些最基本而必要的概念模棱兩可,使得教程再多、再優秀,也沒多少人能消化、能記住。於是我抱着試試看的心態,在經過幾番潤色過,將自己覆盤的結果,在小會上分享出來供同事們享用。想不到原本不屑聽的幾個同事,在聽完這番講解後,連說真香。
所以如果你因爲本文,而對 Activity
乃至向上追溯的 View
、Window
、WindowManager
、WindowManagerService
、Surface
、Surface Flinger
各自的起源、職責邊界以及相互間的關係有了最基本的感性認識,繼而不知不覺地開始有了一絲絲好奇,推動你深入地去探究,那我的願望也就達到了。
我是一塊板磚
我是一塊運行着原始 Android 系統的板磚。我有一塊屏幕,人們只要通過硬件抽象層(HAL)的代碼對屏幕發起指令,屏幕上就可以顯示人們想看到的內容。然而這麼做過於原始,也不契合板磚的使用場景。
於是有人考慮在 HAL 之上的運行時層(ART)用 C++ 封裝一個服務,該服務的名稱就叫 Surface Flinger。
我是 Surface Flinger
我是 Surface Flinger,我的職責是專門負責 UI 內容的渲染。
人們想要在屏幕上渲染出什麼內容,都可以通過我來間接地與屏幕打交道。這就好比你在電腦上排版好的文檔,只需通過打印機驅動程序這個中介,就能幫助你將文檔內容輸出到紙上。
至於內容本身究竟有些什麼,這我不管,我只負責統一地、有序地將內容安排成輸出設備能理解的方式,來實現輸出。
我是 Window
這塊板磚的主人不僅想要渲染 UI,還想要窗口,於是在應用框架層,通過 Java 封裝了我。
人如其名,我就是一個窗口,我負責可視化內容的排版,然後將排版結果,通過我的上司 WindowManager,通過進程通信的方式,去與後臺服務 WindowManagerService 通信,最終遞交到 Surface Flinger 來輸出和呈現。
Surface Flinger 爲我們每一個 Window 都映射了一塊 Surface,來用於管理和渲染屏幕內容。
然而作爲一個 Window,我也有我的苦衷。
我是一個會套娃的 View
主人因爲經常聽 Window 大哥抱怨排版的負擔太重,於是用組合模式封裝了我。我的 “有容乃大” 版本:ViewGroup,因爲組合模式,而能夠在自身內部存在更多的 View 或 ViewGroup,這使得我們從結構上來看,就像套娃。
託遞歸的福,我們的排版工作:Measure、Layout、Draw,可以自己通過如此般的遞歸,自下往上地完成。然後 Window 大哥就可以直接拿着我們的排版結果,去向上司交差啦。
…… 所以,Window 成了摸魚般的存在嗎?
本來 Window 正尋思着,日子過得這般清閒自在,沒想到好日子到頭 —— 主人不僅要一個窗口,還想要多窗口。這多窗口它就涉及到窗口間的切換、通信等等,甚是麻煩,這些髒活累活要是交給以後的開發者來幹,那我不得留下一世罵名、遺臭萬年??!
想到這裏我就感覺哆嗦,不行,爲了我一世英名,我得向主人進言。
其實早在 20000 多年前,女媧造人的時候,便採用了神級的模板方法模式,將一系列的通用功能都封裝好,只暴露一些 DNA 接口,以供後來者隨機輸入和演變。
換言之,主人只需以模板方法模式的方式將我重新封裝,並且編寫一套管理窗口的任務和返回棧機制在背地裏運籌帷幄,那麼未來的開發者就只需繼承我,而得到一個簡練的配置模板,從而在模板上面輸入他們的定製內容,以得到他們想要的結果。
於是我改名叫 Activity
Window 成了我永恆不變的信仰,存留在我的體內。對於開發者來說,我就是個待繼承的 Activity,開發者通過繼承我,拿到的就是一個個簡練的模板。
對系統來說,我的本質仍是被管理的窗口,系統能夠管理我和其他窗口的切換和通信。
對開發者來說,我的本質是視圖控制器,開發者通過我可以控制 View 以他們想要的方式進行排版,並且在特殊狀況下保存和恢復 View 的排版內容。
綜上
- 最開始只有一塊運行着原始 Android 系統的板磚。
- Surface Flinger 的出現是爲了更加方便地完成 UI 渲染。
- Window 的出現是爲了管理 UI 內容的排版。
- Window 不堪重負於是將責任下發到 View 身上。
- View 通過組合模式,在遞歸的幫助下蹭蹭蹭地完成排版工作。
- Activity 的出現是爲了滿足多窗口管理和傻瓜式視圖管理的需要。
所以 Activity 的知識邊界無非就是生命週期、特殊狀況導致的重建、多窗口跳轉(啓動模式、intent)、視圖的加載和優化等等。
這樣說,你理解了嗎?
粉絲技術裙: