概述
Android 從一誕生到現(xiàn)在已經(jīng)發(fā)布的 7.0 版本践宴,卡頓和不流暢問(wèn)題卻一直被人們所詬病哨查≡赡遥客觀地來(lái)講弦疮,Android 的流暢性確實(shí)一直不給力,哪怕是某些大廠的 App 蜘醋,也都不同程度地存在卡頓問(wèn)題胁塞。從開發(fā)角度來(lái)說(shuō),每個(gè)開發(fā)者都應(yīng)該關(guān)注下性能優(yōu)化堂湖,在平時(shí)的開發(fā)工作中注意一些細(xì)節(jié)闲先,盡可能地去優(yōu)化應(yīng)用。
在 Android 開發(fā)中无蜂,UI 可以說(shuō)是每個(gè) App 使用頻率很高的伺糠,隨著 UI 越來(lái)越多,布局的重復(fù)性斥季、復(fù)雜度也會(huì)隨之增長(zhǎng)训桶,UI 設(shè)計(jì)或者布局不慎,就會(huì)引起過(guò)度繪制或者造成 UI 卡頓的情況酣倾,這樣使得 UI 性能的優(yōu)化舵揭,顯得至關(guān)重要,UI 的質(zhì)量也是產(chǎn)品質(zhì)量的一部分躁锡。
2015年初午绳,Google 發(fā)布了關(guān)于 Android 性能優(yōu)化典范的專題,一共16個(gè)短視頻映之,每個(gè)3-5分鐘拦焚,幫助開發(fā)者創(chuàng)建更快更優(yōu)秀的 Android App蜡坊。課程專題不僅僅介紹了 Android 系統(tǒng)中有關(guān)性能問(wèn)題的底層工作原理,同時(shí)也介紹了如何通過(guò)工具來(lái)找出性能問(wèn)題以及提升性能的建議赎败。今天我們就其中之一 Android 渲染機(jī)制開始講起秕衙。
Android渲染機(jī)制
渲染性能
大多數(shù)用戶感知到的卡頓等性能問(wèn)題的最主要根源都是因?yàn)殇秩拘阅堋脑O(shè)計(jì)師的角度僵刮,他們希望 App 能夠有更多的動(dòng)畫据忘,圖片等時(shí)尚元素來(lái)實(shí)現(xiàn)流暢的用 戶體驗(yàn)。但是 Android 系統(tǒng)很有可能無(wú)法及時(shí)完成那些復(fù)雜的界面渲染操作搞糕。Android 系統(tǒng)每隔16ms發(fā)出 VSYNC 信號(hào)勇吊,觸發(fā)對(duì) UI 進(jìn)行渲染, 如果每次渲染都成功窍仰,這樣就能夠達(dá)到流暢的畫面所需要的60fps萧福,為了能夠?qū)崿F(xiàn)60fps,這意味著程序的大多數(shù)操作都必須在16ms內(nèi)完成辈赋。
<img src="http://upload-images.jianshu.io/upload_images/2153668-540bd95044067551.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" />
如果你的某個(gè)操作花費(fèi)時(shí)間是24ms,系統(tǒng)在得到VSYNC信號(hào)的時(shí)候就無(wú)法進(jìn)行正常渲染膏燕,這樣就發(fā)生了丟幀現(xiàn)象钥屈。那么用戶在32ms內(nèi)看到的會(huì)是同一幀畫面。
<img src="http://upload-images.jianshu.io/upload_images/2153668-64ce9db72b29bc61.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" />
用戶容易在 UI 執(zhí)行動(dòng)畫或者滑動(dòng) ListView 的時(shí)候感知到卡頓不流暢坝辫,是因?yàn)檫@里的操作相對(duì)復(fù)雜篷就,容易發(fā)生丟幀的現(xiàn)象,從而感覺(jué)卡頓近忙。有很多原 因可以導(dǎo)致丟幀竭业,也許是因?yàn)槟愕?layout 太過(guò)復(fù)雜,無(wú)法在16ms內(nèi)完成渲染及舍,有可能是因?yàn)槟愕?UI 上有層疊太多的繪制單元未辆,還有可能是因?yàn)閯?dòng)畫執(zhí)行的次數(shù)過(guò)多。這些都會(huì)導(dǎo)致CPU或者GPU負(fù)載過(guò)重锯玛。
渲染組件
對(duì)于上面提到的 CUP 和 GPU咐柜,就需要我們了解 Android 的渲染機(jī)制,Android 的渲染主要分為兩個(gè)組件:
- CPU
- GPU
他們主要的工作是:
<img src="http://upload-images.jianshu.io/upload_images/2153668-127c14718ee29fca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" />
渲染操作通常依賴于兩個(gè)核心組件:CPU 與 GPU攘残。CPU負(fù)責(zé)包括 Measure拙友,Layout,Record歼郭,Execute 的計(jì)算操作遗契,把 UI 組件計(jì)算成Polygons,Texture紋理病曾,然后交給GPU進(jìn)行柵格化渲染牍蜂。漾根。CPU 通常存在的問(wèn)題的原因是存在非必需的視圖組件,它不僅僅會(huì)帶來(lái)重復(fù)的計(jì)算操作捷兰,而且還會(huì)占用額外的 GPU 資源立叛;GPU 通常存在的問(wèn)題的原因是存在過(guò)度繪制。
Activity 如何將復(fù)雜的UI轉(zhuǎn)換成用戶看得懂的圖像并繪制到屏幕上贡茅?
這是由格柵化操作完成的秘蛇,所謂的柵格化就是繪制那些 Button,Shape顶考,Path赁还,String,Bitmap 等組件最基礎(chǔ)的操作驹沿。它把那些組件拆分到不同的像素上進(jìn)行顯示艘策,說(shuō)的俗氣一點(diǎn),就是解決那些復(fù)雜的 XML 布局文件和標(biāo)記語(yǔ)言渊季,使之轉(zhuǎn)化成用戶能看懂的圖像朋蔫,但是這不是直接轉(zhuǎn)換的,XML 布局文件需要在 CPU 中首先轉(zhuǎn)換為多邊形或者紋理却汉,然后再傳遞給 GPU 進(jìn)行柵格化驯妄。
說(shuō)完了概念,繼續(xù)分析上圖合砂,如何對(duì) CPU 和 GPU 進(jìn)行優(yōu)化呢青扔?
- 通過(guò)Hierarchy Viewer去檢測(cè)渲染效率,去除不必要的嵌套翩伪;
- 通過(guò)Show GPU Overdraw去檢測(cè)Overdraw微猖,最終可以通過(guò)移除不必要的背景以及使用canvas.clipRect解決大多數(shù)問(wèn)題。
到這里缘屹,你可能對(duì) UI 優(yōu)化還是不太理解凛剥,畢竟概念是枯燥的,下面我們就深入研究?jī)?yōu)化轻姿。