Android 渲染機(jī)制深入理解
基礎(chǔ)知識(shí)
CPU: 中央處理器,它集成了運(yùn)算,緩沖,控制等單元,包括繪圖功能.CPU將對(duì)象處理為多維圖形,紋理(Bitmaps、Drawables等都是一起打包到統(tǒng)一的紋理)。
GPU:一個(gè)類(lèi)似于CPU的專(zhuān)門(mén)用來(lái)處理Graphics的處理器, 作用用來(lái)幫助加快格柵化操作,當(dāng)然,也有相應(yīng)的緩存數(shù)據(jù)(例如緩存已經(jīng)光柵化過(guò)的bitmap等)機(jī)制。
OpenGL ES:是手持嵌入式設(shè)備的3DAPI,跨平臺(tái)的、功能完善的2D和3D圖形應(yīng)用程序接口API,有一套固定渲染管線流程. OpenGL ES詳解
DisplayList 在Android把XML布局文件轉(zhuǎn)換成GPU能夠識(shí)別并繪制的對(duì)象。這個(gè)操作是在DisplayList的幫助下完成的。DisplayList持有所有將要交給GPU繪制到屏幕上的數(shù)據(jù)信息。
格柵化 是 將圖片等矢量資源,轉(zhuǎn)化為一格格像素點(diǎn)的像素圖,顯示到屏幕上。
垂直同步VSYNC:讓顯卡的運(yùn)算和顯示器刷新率一致以穩(wěn)定輸出的畫(huà)面質(zhì)量。它告知GPU在載入新幀之前,要等待屏幕繪制完成前一幀。下面的三張圖分別是GPU和硬件同步所發(fā)生的情況,Refresh Rate:屏幕一秒內(nèi)刷新屏幕的次數(shù),由硬件決定,例如60Hz.而Frame Rate:GPU一秒繪制操作的幀數(shù),單位是30fps,正常情況過(guò)程圖如下:
渲染機(jī)制分析渲染流程簡(jiǎn)介
Android整體的繪制流程如下:
UI對(duì)象—->CPU處理為多維圖形,紋理 —–通過(guò)OpeGL ES接口調(diào)用GPU—-> GPU對(duì)圖進(jìn)行光柵化(Frame Rate ) —->硬件時(shí)鐘(Refresh Rate)—-垂直同步—->投射到屏幕
Android系統(tǒng)每隔16ms發(fā)出VSYNC信號(hào)(1000ms/60=16.66ms),觸發(fā)對(duì)UI進(jìn)行渲染, 如果每次渲染都成功,這樣就能夠達(dá)到流暢的畫(huà)面所需要的60fps,為了能夠?qū)崿F(xiàn)60fps,這意味著計(jì)算渲染的大多數(shù)操作都必須在16ms內(nèi)完成。
渲染時(shí)間線
正常情況下Android的GPU會(huì)在16ms完成頁(yè)面的繪制,如果一幀畫(huà)面渲染時(shí)間超過(guò)16ms的時(shí)候,垂直同步機(jī)制會(huì)讓顯示器硬件 等待GPU完成柵格化渲染操作,然后再次繪制界面,這樣就會(huì)看起來(lái)畫(huà)面停頓。
當(dāng)GPU渲染速度過(guò)慢,就會(huì)導(dǎo)致如下情況,某些幀顯示的畫(huà)面內(nèi)容就會(huì)與上一幀的畫(huà)面相同。
渲染常見(jiàn)問(wèn)題
GPU過(guò)度繪制
OverDraw是開(kāi)發(fā)中常見(jiàn)的優(yōu)化點(diǎn),是指一個(gè)界面出現(xiàn)層層繪制的情況,如:
我們可以使用一些第三方工具來(lái)查看是否過(guò)渡繪制。如小米魅族。
任何時(shí)候View中的繪制內(nèi)容發(fā)生變化時(shí),都會(huì)重新執(zhí)行創(chuàng)建DisplayList,渲染DisplayList,更新到屏幕上等一 系列操作。這個(gè)流程的表現(xiàn)性能取決于你的View的復(fù)雜程度,View的狀態(tài)變化以及渲染管道的執(zhí)行性能。
當(dāng)View的大小發(fā)生改變,DisplayList就會(huì)重新創(chuàng)建,然后再渲染,而當(dāng)View發(fā)生位移,則DisplayList不會(huì)重新創(chuàng)建,而是執(zhí)行重新渲染的操作。
所以當(dāng)界面過(guò)于復(fù)雜的時(shí)候,DisplayList繪制界面就會(huì)出現(xiàn)延遲而造成卡頓。
我們可以使用渲染工具檢測(cè),工具中,不同手機(jī)呈現(xiàn)方式可能會(huì)有差別.分別關(guān)于StatusBar,NavBar,激活的程序Activity區(qū)域的GPU Rending信息。激活的程序Activity區(qū)域的GPU Rending信息。
我們打開(kāi)手機(jī)的GPU Rending呈現(xiàn)的信息,我們以魅族為例:
說(shuō)明:每一條柱狀線都包含三部分,
藍(lán)色代表測(cè)量繪制Display List的時(shí)間,
紅色代表OpenGL渲染Display List所需要的時(shí)間,
黃色代表CPU等待GPU處理的時(shí)間。
Android渲染優(yōu)化
讀懂Android的渲染機(jī)制對(duì)于優(yōu)化,特別是在寫(xiě)布局的時(shí)候是很有幫助的。減少布局層級(jí),減少GPU的渲染這對(duì)我們提供app的質(zhì)量是很有幫助的。
去掉不必要的界面:
布局層級(jí)優(yōu)化
使用Hierarchy Viewer工具可以查看界面的層級(jí),關(guān)于這塊的介紹請(qǐng)查看:Android布局優(yōu)化
圖片格式選擇
Android的界面能用png最好是用png了,因?yàn)?2位的png顏色過(guò)渡平滑且支持透明。jpg是像素化壓縮過(guò)的圖片,質(zhì)量已經(jīng)下降了,再拿來(lái)做9path的按鈕和平鋪拉伸的控件必然慘不忍睹,要盡量避免。有條件的可以選擇webpp,這種格式的圖片占據(jù)的大小比較小,并且能滿足手機(jī)顯示的需要。
當(dāng)背景無(wú)法避免,盡量用Color.TRANSPARENT
因?yàn)橥该魃獵olor.TRANSPARENT是不會(huì)被渲染的,他是透明的。
所以我們?cè)谠O(shè)置界面的時(shí)候需要做一個(gè)判斷:
Bean bean=list.get(i); if (bean.img == 0) { Picasso.with(getContext()).load(android.R.color.transparent).into(holder.imageView); holder.imageView.setBackgroundColor(bean.backPic); } else { Picasso.with(getContext()).load(bean.img).into(holder.imageView); holder.imageView.setBackgroundColor(Color.TRANSPARENT); }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫(huà)效果(八)
這篇文章主要為大家詳細(xì)介紹了Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫(huà)效果的第八篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android 實(shí)現(xiàn)云知聲版離線語(yǔ)音合成
這篇文章主要介紹了Android 實(shí)現(xiàn)云知聲版離線語(yǔ)音合成,目前云知聲提供免費(fèi)的離線TTS,功能也比較簡(jiǎn)單,合成的語(yǔ)音也比較生硬,如果對(duì)合成的語(yǔ)音要求不高的話可以考慮接入。具體合成需要的小伙伴可以參考下面文章內(nèi)容2022-06-06Android基于自帶的DownloadManager實(shí)現(xiàn)下載功能示例
這篇文章主要介紹了Android基于自帶的DownloadManager實(shí)現(xiàn)下載功能,結(jié)合實(shí)例形式分析了DownloadManager實(shí)現(xiàn)下載功能的具體操作步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-08-08Android使用DatePickerDialog顯示時(shí)間
本文將結(jié)合實(shí)例代碼,介紹Android使用DatePickerDialog顯示時(shí)間,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07android app跳轉(zhuǎn)應(yīng)用商店實(shí)現(xiàn)步驟
這篇文章主要為大家介紹了android app跳轉(zhuǎn)應(yīng)用商店實(shí)現(xiàn)步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11Android自定義動(dòng)態(tài)壁紙開(kāi)發(fā)(時(shí)鐘)
今天小編就為大家分享一篇關(guān)于Android自定義動(dòng)態(tài)壁紙開(kāi)發(fā)(時(shí)鐘),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01詳解Android Studio安裝ButterKnife插件(手動(dòng)安裝)
這篇文章主要介紹了詳解AndroidStudio安裝ButterKnife插件(手動(dòng)安裝),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08Android 中在有序廣播中添加自定義權(quán)限的實(shí)例
這篇文章主要介紹了Android 中在有序廣播中添加自定義權(quán)限的實(shí)例的相關(guān)資料,這里對(duì)有序廣播的用法進(jìn)行了詳細(xì)介紹并附有簡(jiǎn)單實(shí)例,需要的朋友可以參考下2017-07-07