UI 優(yōu)化系列專題主到,來(lái)聊一聊 Android 渲染相關(guān)知識(shí),主要涉及 UI 渲染背景知識(shí)躯概、如何優(yōu)化 UI 渲染兩部分內(nèi)容登钥。
UI 優(yōu)化系列專題
- UI 渲染背景知識(shí)
《View 繪制流程之 setContentView() 到底做了什么?》
《View 繪制流程之 DecorView 添加至窗口的過(guò)程》
《深入 Activity 三部曲(3)View 繪制流程》
《Android 之 LayoutInflater 全面解析》
《關(guān)于渲染娶靡,你需要了解什么牧牢?》
《Android 之 Choreographer 詳細(xì)分析》
- 如何優(yōu)化 UI 渲染
《Android 之如何優(yōu)化 UI 渲染(上)》
《Android 之如何優(yōu)化 UI 渲染(下)》
UI 渲染可能是諸多性能問(wèn)題中最容易被察覺(jué)到的,Android 開(kāi)發(fā)既要面對(duì)各式各樣的手機(jī)屏幕尺寸和分辨率姿锭,還要與“兇殘”的產(chǎn)品和 UI 設(shè)計(jì)師過(guò)招塔鳍。在正確實(shí)現(xiàn)復(fù)雜、炫酷的 UI 設(shè)計(jì)的同時(shí)呻此,還需要保證流程的用戶體驗(yàn)轮纫。更加不幸的是,最近幾年這個(gè)趨勢(shì)似乎愈演愈烈:劉海屏焚鲜、水滴屏掌唾、全面屏,還有即將推出的的柔性折疊屏忿磅,UI 適配將變得越來(lái)越復(fù)雜糯彬。
UI 渲染的背景知識(shí)
Android 的圖形渲染框架十分復(fù)雜,不同版本的差異也比較大贝乎。但是無(wú)論怎么樣情连,它們最終都是為了將我們代碼中的 View 或者元素顯示到屏幕上。
而屏幕作為直接面對(duì)用戶的手機(jī)硬件览效,類似厚度却舀、色彩、功耗等都是廠家非常關(guān)注的锤灿。從早期的黑白屏功能機(jī)挽拔,到現(xiàn)在的超大的全面屏,我們先來(lái)看看手機(jī)屏幕的發(fā)展歷程但校。
1. 屏幕與適配
Android 的碎片化問(wèn)題由來(lái)已久螃诅,并且另每個(gè) Android 開(kāi)發(fā)痛心疾首,而屏幕的差異化正是這些碎片化問(wèn)題的“中心”状囱。屏幕從 3 英寸到 10 英寸术裸,分辨率從 320 到 2160 應(yīng)有盡有,對(duì)我們 UI 適配造成很大困難亭枷。
除此之外袭艺,材質(zhì)也是屏幕至關(guān)重要的一個(gè)評(píng)判因素。目前智能手機(jī)主流的屏幕可分為兩大類:一種是 LCD(Liquid Crystal Display)叨粘,即液晶顯示器猾编;另一種是 OLED(Organic Light-Emitting Diode )即有機(jī)發(fā)光二極管瘤睹。
最新的旗艦機(jī)例如 iPhone 11 Pro / Max 已經(jīng)開(kāi)始使用超視網(wǎng)膜 OLED 顯示屏技術(shù),OLED 提供令人驚嘆的高對(duì)比度和高分辨率答倡,相比 LCD 屏幕轰传,OLED 無(wú)需背光組件,而是由每個(gè)像素自行發(fā)光瘪撇,因此顯示屏變得更薄获茬。另外 OLED 屏幕在可彎曲程度以及耗電方面都更具有優(yōu)勢(shì)。正因?yàn)檫@些優(yōu)勢(shì)设江,全面屏锦茁、曲面屏以及未來(lái)的柔性折疊屏,使用的都是 OLED 材質(zhì)叉存。關(guān)于 OLED 與 LCD 的具體差別码俩,可以參考《OLED 和 LCD 區(qū)別》和《手機(jī)屏幕的前世今生,可能比你想象的還精彩》歼捏,不過(guò)目前 OLED 的成本相比 LCD 要高很多稿存。
對(duì)于屏幕適配,Android 推薦使用 dp 作為尺寸單位來(lái)適配 UI瞳秽,通過(guò) dp 加上自適應(yīng)布局基本可以解決屏幕碎片化問(wèn)題瓣履,這也是 Android 推薦使用的屏幕兼容性適配方案。因此每個(gè) Android 開(kāi)發(fā)都應(yīng)該清楚 px练俐、dp袖迎、dpi、ppi腺晾、density 這些概念燕锥。具體可以參考《Android 屏幕適配全攻略》
2. CPU 與 GPU
除了屏幕,UI 渲染還要依賴另外兩個(gè)核心的硬件:CPU 和 GPU悯蝉。
- CPU(Central Processing Unit归形,中央處理器),是計(jì)算機(jī)系統(tǒng)的運(yùn)算和控制核心鼻由,是信息處理暇榴、程序運(yùn)行的最終執(zhí)行單元;
- GPU(Graphics Processin Unit蕉世,圖形處理器)蔼紧,是一種專門用于圖像運(yùn)算的處理器,在計(jì)算機(jī)系統(tǒng)中通常被稱為 "顯卡"的核心部件就是 GPU狠轻。
UI 組件在繪制到屏幕之前奸例,都需要經(jīng)過(guò) Rasterization(柵格化)操作,而柵格化又是一個(gè)非常耗時(shí)的操作哈误。
- Rasterization 柵格化是繪制那些 Button哩至、Shape、Path蜜自、String菩貌、Bitmap 等顯示組件最基礎(chǔ)的操作。柵格化將這些 UI 組件拆分到顯示器的不同像素上進(jìn)行顯示重荠。這是一個(gè)非常耗時(shí)的操作箭阶,GPU 的引入就是為了加快柵格化。
GPU 的由來(lái)
在沒(méi)有 GPU 的時(shí)代戈鲁,UI 的繪制任務(wù)完全由 CPU 完成仇参, CPU 既要負(fù)責(zé) UI 繪制還要負(fù)責(zé)內(nèi)存管理、邏輯運(yùn)算等其他任務(wù)婆殿,這就導(dǎo)致 CPU 的任務(wù)繁多诈乒,因此性能也會(huì)大打折扣。
CPU 與 GPU 在結(jié)構(gòu)設(shè)計(jì)上完全不同婆芦,如下圖:
黃色 Control 為控制器怕磨,用于協(xié)調(diào)控制整個(gè) CPU 的運(yùn)行,包括指令讀取消约、控制其他模塊的運(yùn)行等肠鲫;
綠色的 ALU(Arithmetic Logic Unit)是算數(shù)邏輯單元,用于進(jìn)行數(shù)學(xué)或粮、邏輯運(yùn)算导饲;
橙色的 Cache 和 DRAM 分別為高速緩存和 RAM,用于存儲(chǔ)信息氯材。
從結(jié)構(gòu)圖可以看出渣锦,CPU 的控制器較為復(fù)雜,而 ALU 數(shù)量較少浓体,因此 CPU 更擅長(zhǎng)各種復(fù)雜的邏輯運(yùn)算泡挺,但不擅長(zhǎng)數(shù)學(xué)尤其是浮點(diǎn)運(yùn)算。
而 GPU 的設(shè)計(jì)正是為實(shí)現(xiàn)大量數(shù)學(xué)運(yùn)算命浴。GPU 的控制器比較簡(jiǎn)單娄猫,但包含大量 ALU。GPU 中的 ALU 使用了并行設(shè)計(jì)生闲,且具有較多的浮點(diǎn)運(yùn)算單元媳溺。可以幫助我們加快柵格化操作碍讯。
從圖中可以看到悬蔽,軟件繪制使用 Skia 庫(kù),它是一款能在低端設(shè)備捉兴,如手機(jī)呈現(xiàn)高質(zhì)量的 2D 跨平臺(tái)圖形框架蝎困,類似 Chrome录语、Flutter 內(nèi)部使用的都是 Skia 庫(kù)。
- 硬件繪制的思想就是通過(guò)底層軟件代碼禾乘,將 CPU 不擅長(zhǎng)的圖形計(jì)算轉(zhuǎn)換成 GPU 專用指令澎埠,由 GPU 完成繪制任務(wù)。
3. OpenGL 與 Vulkan
- OpenGL(Open Graphics Library):OpenGL 是一個(gè)跨平臺(tái)的圖形API始藕,它為 3D 圖形處理硬件指定了一個(gè)標(biāo)準(zhǔn)的軟件接口蒲稳。
- OpenGL ES (Embedded Systems):OpenGL ES 是針對(duì)嵌入式設(shè)備的 OpenGL 規(guī)范的一種變體。Android 支持多個(gè)版本的 OpenGL ES API伍派。
- Vulkan:它是一個(gè)低開(kāi)銷江耀、跨平臺(tái)的 3D 圖形和計(jì)算 API。Vulkan 的目標(biāo)是跨所有平臺(tái)的高性能實(shí)時(shí) 3D 圖形應(yīng)用程序诉植,旨在提供更高的性能和更均衡的 CPU / GPU 使用祥国。
硬件加速繪制就是通過(guò) GPU 來(lái)進(jìn)行渲染,GPU 作為一個(gè)硬件倍踪,用戶空間是無(wú)法直接使用的系宫,它是由 GPU 廠商按照 OpenGL 規(guī)范實(shí)現(xiàn)的驅(qū)動(dòng)間接進(jìn)行使用。也就是說(shuō)建车,如果一個(gè)設(shè)備支持 GPU 硬件加速渲染扩借,那么當(dāng) Android 應(yīng)用程序調(diào)用 Open GL 接口來(lái)繪制 UI 時(shí),Android 應(yīng)用程序的 UI 就是通過(guò)硬件加速技術(shù)進(jìn)行渲染的缤至。
在官方硬件加速的文檔中潮罪,可以看到很多 OpenGL API 都有相應(yīng)的 Android API Level 限制。
這主要是受 OpenGL ES 版本與系統(tǒng)支持的限制领斥,直到 Android P嫉到,仍然有 3 個(gè) API 是沒(méi)有支持的。對(duì)于不支持的 API月洛,只能使用軟件繪制模式何恶,渲染的性能將會(huì)大大降低。
OpenGL ES版本 | Android 版本 |
---|---|
OpenGL ES 1.0 和 1.1 | Android 1.0 支持 |
OpenGL ES 2.0 | Android 2.2 支持 |
OpenGL ES 3.0 | Android 4.3 支持 |
OpenGL ES 3.1 | Android 5.0 支持 |
OpenGL ES 3.2 | Android 7.0 支持 |
Android 7.0 把 OpenGL ES 升級(jí)到最新的 3.2 版本的實(shí)時(shí)嚼黔,還添加了對(duì) Vulkan 的支持细层。Vulkan 的設(shè)計(jì)目標(biāo)是取代 OpenGL,Vulkan 是一個(gè)相當(dāng)?shù)图?jí)別的 API唬涧,并且提供并行的任務(wù)處理疫赎。Vulkan 還能夠渲染 2D 圖形應(yīng)用程序。除了其較低的 CPU 使用率碎节,Vulkan 還能夠更好地在多個(gè) CPU 內(nèi)核之間分配工作捧搞。在功耗、多核優(yōu)化提升繪圖調(diào)用上有著非常明顯的優(yōu)勢(shì)。
Android 的圖形組件
Android 的 UI 渲染性能是 Google 長(zhǎng)期以來(lái)非常重視的胎撇,基本每次 Google I/O 都會(huì)花很多篇幅講這一塊內(nèi)容介粘。每個(gè)開(kāi)發(fā)者都希望自己的應(yīng)用都可以做到 60 fps 如絲般順滑,在了解 Android 的渲染之前晚树,需要先了解下 Android 圖形系統(tǒng)的整體架構(gòu)碗短,以及它包含的主要組件。
Image Stream Produces:圖像流生產(chǎn)方题涨,應(yīng)用程序內(nèi)繪制到 Surface 的圖形(xml / Java 實(shí)現(xiàn)的圖形,或者視頻)
Hardware Composer:硬件合成器总滩,它是顯示控制器的硬件抽象纲堵。
Gralloc:Graphic memory allocator 用來(lái)分配圖形緩沖區(qū)內(nèi)存。
如果把應(yīng)用程序圖形渲染過(guò)程當(dāng)做一次繪畫(huà)過(guò)程闰渔,那么繪畫(huà)過(guò)程中 Android 的各個(gè)圖形組件的作用是:
畫(huà)筆:Skia 或者 OpenGL席函。我們可以用 Skia 畫(huà)筆繪制 2D 圖形,也可以用 OpenGL 來(lái)繪制 2D / 3D 圖形冈涧。正如前面所說(shuō)茂附,前者使用 CPU 繪制,后者使用 GPU 繪制督弓。
畫(huà)紙:Surface营曼。所有的元素都在 Surface 這張畫(huà)紙上進(jìn)行繪制和渲染。在 Android 中愚隧,Window 是 View 的容器蒂阱,每個(gè)窗口都會(huì)關(guān)聯(lián)一個(gè) Surface。而 WindowManager 則負(fù)責(zé)管理這些窗口狂塘,并且把它們的數(shù)據(jù)傳遞給 SurfaceFlinger录煤。
畫(huà)板:Graphic Buffer。Graphic Buffer 緩沖用于應(yīng)用于應(yīng)用程序圖形的繪制荞胡,在 Android 4.1 之前使用的是雙緩沖機(jī)制妈踊;在 Android 4.1 之后,使用的是三緩沖機(jī)制泪漂。
顯示:SurfaceFlinger廊营。它將 WindowManger 提供的所有 Surface,通過(guò)硬件合成器 Hardware Composer 合成并輸出到顯示屏窖梁。
使用畫(huà)筆 Skia / OpenGL 將內(nèi)容繪制到 Surface 上赘风,繪制的過(guò)程中如果使用 Open GL 渲染,那便是硬件加速纵刘,否則純靠 CPU 繪制渲染柵格化的過(guò)程就叫軟件繪制邀窃。對(duì)于硬件繪制,我們通過(guò)調(diào)用 OpenGL ES 接口利用 GPU 完成繪制。
Why 60 fps瞬捕?
關(guān)于 Android 的渲染鞍历,大家肯定聽(tīng)說(shuō)過(guò)每秒 60 幀和 16ms 的限制問(wèn)題,你是否有想過(guò)為什么是這些數(shù)字肪虎?如果你是對(duì)于性能要求較高的開(kāi)發(fā)者劣砍,這樣的技術(shù)細(xì)節(jié)是非常值得深入了解的。
由于人類眼睛特殊的生理結(jié)構(gòu)扇救,并不像相機(jī)那樣有圖像快照送到大腦刑枝;相反,大腦在不停地處理眼睛傳遞給他的視覺(jué)信號(hào)迅腔,所以對(duì)于人類的大腦來(lái)說(shuō)并沒(méi)有幀或者快照的概念装畅,人類眼睛對(duì)于運(yùn)動(dòng)的概念來(lái)自于靜止的幀。
12 fps:每秒達(dá)到 10 ~ 12 幀以上才可以被感知到運(yùn)動(dòng)及變化沧烈,但是這樣的速率是非常不流暢的掠兄,只有幀率超過(guò)每秒 24 幀的時(shí)候,才會(huì)被察覺(jué)為流暢的運(yùn)動(dòng)及變化锌雀。
24fps:每秒 24 幀在電影界是黃金標(biāo)準(zhǔn)蚂夕,24 幀的速度足夠使畫(huà)面運(yùn)動(dòng)的非常流暢,而且 24 幀的電影預(yù)算也能滿足成本的要求腋逆,這也是為什么在過(guò)去的 50 年里婿牍,絕大多數(shù)的電影都使用 24 幀每秒的速率。
現(xiàn)在惩歉,每秒 30 幀對(duì)于電影來(lái)說(shuō)綽綽有余牍汹,但是對(duì)于那些復(fù)雜絢麗的電影特效,它的視覺(jué)效果還是難以令人信服柬泽。
- 60fps:實(shí)際上每秒 60fps 的速度才是真正的黃金標(biāo)準(zhǔn)慎菲,60 幀的速度非常流暢,絕大多數(shù)人都察覺(jué)不到比 60 幀還高的視覺(jué)體驗(yàn)锨并。
Android 系統(tǒng)每間隔 16ms 發(fā)出一次 VSYNC 信號(hào)露该,觸發(fā)對(duì) UI 的渲染任務(wù);為了能夠?qū)崿F(xiàn)流暢的畫(huà)面第煮,這就意味著應(yīng)該始終讓?xiě)?yīng)用保持在 60 幀每秒解幼,即每幀工作的準(zhǔn)備時(shí)間僅有 16ms。
Android 渲染的演進(jìn)
跟耗電一樣撵摆,Android 的 UI 渲染性能也是 Google 長(zhǎng)期以來(lái)非常重視的,基本每次 Google I/O 都會(huì)花很多篇幅講這一塊害晦。每個(gè)開(kāi)發(fā)者都希望自己的應(yīng)用可以做到 60 fps 如絲般順滑特铝,不過(guò)相比 iOS 系統(tǒng),Android 的渲染性能一直被人詬病。
Android 系統(tǒng)為了彌補(bǔ)跟 iOS 的差距鲫剿,在每個(gè)版本都做了大量的優(yōu)化鳄逾。接下來(lái)我們通過(guò)演進(jìn)的方式看看 Android 系統(tǒng)在渲染方面都做了哪些努力。
1. Android 4.0 開(kāi)啟硬件加速
在 Android 3.0 之前灵莲,或者沒(méi)有啟用硬件加速時(shí)雕凹,系統(tǒng)都會(huì)使用軟件方式來(lái)渲染 UI。
整個(gè)流程如上圖所示:
Surface政冻。每個(gè) View 都由某一個(gè)窗口管理枚抵,而每一個(gè)窗口都會(huì)關(guān)聯(lián)有一個(gè) Surface。
Canvas明场。通過(guò) Surface 的 lock 函數(shù)獲得一個(gè) Canvas俄精,Canvas 可以簡(jiǎn)單理解為 Skia 底層接口的封裝。
Graphic Buffer榕堰。SurfaceFlinger 會(huì)幫助我們托管一個(gè) BufferQueue,我們從 BufferQueue 中拿到 Graphic Buffer嫌套,然后通過(guò) Canvas 以及 Skia 將繪制內(nèi)容柵格化到上面逆屡。
SurfaceFlinger。通過(guò) Swap Buffer 把 Front Graphic Buffer 的內(nèi)容交給 SurfaceFlinger踱讨,最后硬件合成器 Hardware Composer 合成并輸出到顯示屏魏蔗。
整個(gè)渲染流程看上去比較簡(jiǎn)單,但是正如前面所說(shuō)痹筛,CPU 對(duì)于圖形處理并不是那么高效莺治,這個(gè)過(guò)程完全沒(méi)有利用 GPU 的高性能。
硬件加速繪制
所以從 Android 3.0 開(kāi)始帚稠,Android 開(kāi)始支持硬件加速谣旁,但是到 Android 4.0 時(shí)才默認(rèn)開(kāi)啟硬件加速。
硬件加速繪制與軟件繪制整個(gè)流程差異非常大滋早,最核心就是通過(guò) GPU 完成 Graphic Buffer 的內(nèi)容繪制榄审。此外硬件繪制還引入了一個(gè) DisplayList 的概念,每個(gè) View 內(nèi)部都有一個(gè) DisplayList杆麸,當(dāng)某個(gè) View 需要重繪時(shí)搁进,將它標(biāo)記為 Dirty。
當(dāng)需要重繪時(shí)昔头,僅僅只需要重繪一個(gè) View 的 DisplayList饼问,而不是像軟件繪制那樣需要向上遞歸。這樣可以大大減少繪圖的操作數(shù)量揭斧,因而提高了渲染效率莱革。
2. Android 4.1 Project Butter
優(yōu)化是無(wú)止境的,Google 在 2012 年的 I/O 大會(huì)上宣布了 Project Butter 黃油計(jì)劃,并且在 Android 4.1 中正式開(kāi)啟了這個(gè)機(jī)制驮吱。
Project Butter 主要包含三個(gè)組成部分茧妒,VSYNC左冬、Triple Buffer 和 Choreographer桐筏。
VSYNC 信號(hào)
其中 VSYNC(Vertical Synchronization)是理解 Project Butter 的核心。對(duì)于 Android 4.0拇砰,CPU 可能會(huì)因?yàn)樵诿ζ渌氖虑槊芳桑瑢?dǎo)致沒(méi)來(lái)得及處理 UI 繪制。
為了解決這個(gè)問(wèn)題除破,Project Butter 引入了 VSYNC牧氮,它類似于時(shí)鐘中斷,每收到 VSYNC 中斷瑰枫,CPU 會(huì)立即準(zhǔn)備 Buffer 數(shù)據(jù)踱葛,由于大部分顯示設(shè)備刷新頻率都是 60 Hz(一秒刷新 60 次),也就是說(shuō)一幀數(shù)據(jù)的準(zhǔn)備都要在 16ms 內(nèi)完成光坝。
這樣應(yīng)用總是在 VSYNC 邊界上開(kāi)始繪制尸诽,而 SurfaceFlinger 總是在 VSYNC 邊界上進(jìn)行合成。這樣可以消除卡頓盯另,并提升圖形的視覺(jué)表現(xiàn)性含。
Triple Buffering(三緩沖機(jī)制)
在 Android 4.1 之前,Android 使用雙緩沖機(jī)制鸳惯。怎么理解呢商蕴?一般來(lái)說(shuō),不同的 View 或者 Activity 都會(huì)共用同一個(gè) Window芝发,也就是共用同一個(gè) Surface绪商。
而每個(gè) Surface 都會(huì)有一個(gè) BufferQueue 緩存隊(duì)列,但是這個(gè)隊(duì)列會(huì)由 SurfaceFlinger 管理辅鲸,通過(guò)匿名共享內(nèi)存機(jī)制與 App 應(yīng)用層交互部宿。
整個(gè)流程如下:
每個(gè) Surface 對(duì)應(yīng)的 BufferQueue 內(nèi)部都有兩個(gè) Graphic Buffer,一個(gè)用于繪制一個(gè)用于系那是瓢湃。應(yīng)用會(huì)把內(nèi)容先繪制到離屏緩沖區(qū)(OffScreen Buffer)理张,在需要顯示時(shí),才把離屏緩沖區(qū)的內(nèi)容通過(guò) Swap Buffer 復(fù)制到 Front Graphic Buffer 中绵患。
這樣 SurfaceFlinge 就拿到了某個(gè) Surface 最終要顯示的內(nèi)容雾叭,但是同一時(shí)間我們可能會(huì)有多個(gè) Surface。這里面可能是不同應(yīng)用的 Surface落蝙,也可能是同一個(gè)應(yīng)用里面類似 SurfaceView 和 TextureView织狐,它們都會(huì)有自己?jiǎn)为?dú)的 Surface暂幼。
這個(gè)時(shí)候 SurfaceFlinger 把所有 Surface 要顯示的內(nèi)容統(tǒng)一交給 Hardware Composer,它會(huì)根據(jù)位置移迫、Z - Order 順序等信息合成為最終屏幕需要顯示的內(nèi)容旺嬉,而這個(gè)內(nèi)容交給系統(tǒng)的幀緩沖區(qū) Frame Buffer 來(lái)顯示(Frame Buffer 是非常底層的,可以理解為屏幕顯示的抽象)厨埋。
如果你理解了雙緩沖機(jī)制的原理邪媳,那就非常容易理解什么是三緩沖區(qū)了。如果只有兩個(gè) Graphic Buffer 緩存區(qū) A 和 B荡陷,如果 CPU / GPU 繪制過(guò)程較長(zhǎng)雨效,超過(guò)了一個(gè) VSYNC 信號(hào)周期,因?yàn)榫彌_區(qū) B 中的數(shù)據(jù)還沒(méi)有準(zhǔn)備完成废赞,所以只能繼續(xù)展示 A 緩沖區(qū)的內(nèi)容徽龟,這樣緩沖區(qū) A 和 B 都分別被顯示設(shè)備和 GPU 占用,CPU 無(wú)法準(zhǔn)備下一幀的數(shù)據(jù)唉地。
如果再提供一個(gè)緩沖區(qū)据悔,CPU、GPU 和顯示設(shè)備都能使用各自的緩沖區(qū)工作耘沼,互不影響极颓。簡(jiǎn)單來(lái)說(shuō),三緩沖機(jī)制就是在雙緩沖機(jī)制的基礎(chǔ)上增加了一個(gè) Graphic Buffer 緩沖區(qū)耕拷,這樣可以最大限度的利用空閑時(shí)間,帶來(lái)的壞處是多使用了一個(gè) Graphic Buffer 所占用的內(nèi)存托享。
Choreographer
Choreographer 本質(zhì)是一個(gè) Java 類骚烧,如果直譯的話為舞蹈指導(dǎo),看到這個(gè)詞不得不贊嘆設(shè)計(jì)者除了 Coding 之外的廣泛視野闰围。舞蹈是有節(jié)奏的赃绊,節(jié)奏使舞蹈的每個(gè)動(dòng)作更加協(xié)調(diào)和連貫;視圖刷新也是如此羡榴,Choreographer 可以接收系統(tǒng)的 VSYNC 信號(hào)碧查,業(yè)界一般通過(guò)它來(lái)監(jiān)控應(yīng)用的幀率。
Choreographer 是線程單例校仑,而且它具有處理當(dāng)前線程 Looper 的能力忠售。
private static final ThreadLocal<Choreographer> sThreadInstance =
new ThreadLocal<Choreographer>() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
//拋出異常。
}
return new Choreographer(looper);
}
};
3. Android 5.0:RenderThread
經(jīng)過(guò) Android 4.1 的 Project Butter 黃油計(jì)劃之后迄沫,Android 的渲染性能有了很大的改善稻扬。不過(guò)你有沒(méi)有注意到這樣一個(gè)問(wèn)題,雖然利用了 GPU 的圖形高性能運(yùn)算羊瘩,但是從計(jì)算 DisplayList泰佳,到通過(guò) GPU 繪制到 Frame Buffer,整個(gè)計(jì)算和繪制都在 UI 主線程中完成。
UI 線程“既當(dāng)?shù)之?dāng)媽”锄俄,任務(wù)過(guò)于繁重窿凤。如果整個(gè)渲染過(guò)程比較耗時(shí),可能造成無(wú)法響應(yīng)用戶的操作黔宛,進(jìn)而出現(xiàn)卡頓的情況近刘。GPU 對(duì)圖形的繪制渲染能力更勝一籌,如果使用 GPU 并在不同線程繪制渲染圖形宁昭,那么整個(gè)流程會(huì)更加順暢跌宛。
正因如此,在 Android 5.0 引入兩個(gè)比較大的改變积仗。一個(gè)是引入了 RenderNode 的概念疆拘,它對(duì) DisplayList 及一些 View 顯示屬性都做了進(jìn)一步封裝。另一個(gè)是引入了 RenderThread寂曹,所有的 GL 命令執(zhí)行都放到這個(gè)線程上哎迄,渲染線程在 RenderNode 中存有渲染幀的所有信息,可以做一些屬性動(dòng)畫(huà)隆圆,這樣即便主線程有耗時(shí)操作的時(shí)候也可以保證動(dòng)畫(huà)流程漱挚。
總結(jié)
今天,我們主要介紹了 UI 渲染的理論知識(shí)渺氧,通過(guò)演進(jìn)的方式進(jìn)一步加深對(duì) Android 渲染機(jī)制的理解旨涝,這對(duì)接下來(lái)要討論的 UI 渲染優(yōu)化會(huì)有很大的幫助。
Android 在 UI 渲染方面相比 iOS 總是被人詬病侣背,人們總說(shuō) iOS 系統(tǒng)更加流程白华,大家對(duì) Android 的 UI 渲染還了解哪些內(nèi)容呢?歡迎大家留言或指正贩耐。
Android 渲染架構(gòu)非常龐大和復(fù)雜弧腥,而且演進(jìn)得非常快潮太,感興趣的朋友可以進(jìn)一步了解學(xué)習(xí)管搪。
- 2018 Google I/O:Drawn out:How Android renders
- 官方文檔:Android 圖形架構(gòu)
- 瀏覽器渲染:一顆像素的誕生
以上便是個(gè)人在學(xué)習(xí) Android 渲染時(shí)的體會(huì)和總結(jié),關(guān)于 UI 渲染大家還了解哪些內(nèi)容铡买?歡迎您的分享更鲁!
文章如果對(duì)你有幫助,就請(qǐng)留個(gè)贊吧奇钞!
擴(kuò)展閱讀
- Android 之 Choreographer 詳細(xì)分析
- Android 之 Project Butter 詳細(xì)介紹
- 深入 Activity 三部曲(1)View 繪制流程之 setContentView() 到底做了什么
- 深入 Activity 三部曲(2)View 繪制流程之 DecorView 添加至窗口的過(guò)程
- 深入 Activity 三部曲(3)View 繪制流程
其他系列專題