Android介面渲染優化

2021-08-29 07:12:13 字數 3458 閱讀 7861

只要在乙個時間段也就是16ms中,cpu和gpu不能正常處理完資料就會產生卡頓.而cpu(**處理器):多快取多分支,適用於複雜的邏輯運算,主要負責measure,layout,record,execute的計算操作;gpu(影象處理器):眾核少快取,適用於結構單一的資料處理,主要負責rasterization(柵格化)操作

實際上最後還是回到measure,layout,和draw上.也就是說上述三個步驟中的某乙個步驟出現了耗時較長的操作,就容易導致介面卡頓。一般來說多發生在draw上。

什麼是過度繪製?

overdraw(過度繪製)描述的是螢幕上的某個畫素在同一幀的時間內被繪製了多次。在多層次重疊的ui結構裡面,如果不可見的ui也在做繪製的操作,會導致某些畫素區域被繪製了多次。這樣就會浪費大量的cpu以及gpu資源。

如何檢測過度繪製

開發者選項->除錯gpu過度繪製->顯示過度繪製區域�

藍色,淡綠,淡紅,深紅代表了4種不同程度的overdraw情況,我們的目標就是儘量減少紅色overdraw,看到更多的藍色區域

如何優化過度繪製

通常,我們使用的theme都會包含了乙個windowbackground,比如theme的如下:

@color/background_material_light
然後通常我們自己的layout下,會另外加一層背景,這就會引起過度繪製,

一般的解決方式把theme下的background移除

或者在activity中的oncreate()下新增

getwindow().setbackgrounddrawable(null);
去除子控制項的背景

在開發中,經常為了一些視覺效果,需要給子控制項附加背景.

如果按照過度繪製的思想來看這個問題的話,那這裡也會村子啊過度繪製的情況,最合理的設想是如果子view有背景,並且跟父view背景不同,那麼應該移除父view的背景,保留子view的背景,這樣就能避免過度繪製了。

不過如果真的嚴格按照這個邏輯來寫**的話,會導致多寫很多**.況且以目前手機的效能來講,x1級別的過度繪製不太會影響到效能。

使用layout inspector去檢視layout的層次結構

老版本android sdk提供的是乙個hierarchy viewer工具,可以用來分析布局深度,

但是在android studio3.1之後,換成了layout inspector,入口在tools-->layout inspector

使用巢狀少的布局

相同層級下,fragment的效率最高,其次是linearlayout

linearlayout對比relativelayout

relativelayout和linearlayout效能比較

使用抽象布局 include、merge 、viewstub

include、merge 、viewstub這三個布局都是官方提供的用於布局優化的

布局重用 include

標籤復用,比起效能上的優化,更大的作用我感覺在xml檔案的優化上

減少布局層級 merge

多用於替換framelayout或者當乙個布局包含另乙個時,標籤消除檢視層次結構中多餘的檢視組。

延遲載入 viewstub

viewstub是乙個不可見的,大小為0的view,能為xml載入減小不少壓力。常用於 進度條、顯示錯誤訊息等不需要第一時間顯示的檢視,inflate()之後會被對應的layout所代替

注:viewstub目前有個缺陷就是還不支援標籤。

使用lint來優化布局的層次結構

analyze->inspect code

布局效能方面的資訊位於android> lint> performance下,我們可以點開它來看下一些優化建議。

下面是lint的一些優化技巧:

使用復合

如果乙個線性布局中包含乙個 imageview 和乙個 textview,可以使用復合來替換掉

合併根節點

如果乙個framelayout 是整個布局的根節點,並且也沒有提供背景、留白等等,那麼可以使用

標籤來替換掉,因為decorview本身就是乙個framelayout。

移除布局中無用的葉子

布局是乙個樹形的結構,如果乙個布局沒有子 view 或者背景,那麼可以把它移除掉(這布局本身就不可見了)。

移除無用的父布局

如果乙個布局沒有兄弟,也不是scrollview 或者根 view,並且也沒有背景,那麼可以把這個父布局移除掉,然後把它的子view移到它的父布局下。

避免過深的層次結構

過多的布局巢狀不利於效能,可以使用更扁平化的布局,如relativelayout、gridlayout、constraintlayout等布局來提高效能。布局預設的最大深度為10

對於不透明的view,只需要渲染一次即可把它顯示出來。但是如果這個view設定了alpha值,則至少需要渲染兩次。這是因為使用了alpha的view需要先知道混合view的下一層元素是什麼,然後再結合上層的view進行blend混色處理。透明動畫、淡入淡出和陰影等效果都涉及到某種透明度,這就會造成了過度繪製。可以通過減少渲染這些透明物件來改善過度繪製。比如:在textview上設定帶透明度alpha值的黑色文字可以實現灰色的效果。但是,直接通過設定灰色的話能夠獲得更好的效能。

cliprect():可以指定一塊矩形區域,只有在這個區域內才會被繪製,其他的區域會被忽視,可以有效的節約cpu與gpu的資源

canvas.cliprect(0, 0,200,200);  //指定(0,0)到(200,200)的矩形區域為繪製區域
quickreject():判斷畫布是否與你指定的矩形相交,藉此來決定是否需要繪製該畫布

boolean skipdraw=canvas.quickreject(new rectf(), canvas.edgetype.aa);
ondraw()中不要建立新的區域性變數以及不要做耗時操作

ondraw()中不要建立新的區域性變數,因為ondraw()方法可能會被頻繁呼叫,大量的臨時物件會導致記憶體抖動,會造成頻繁的gc,從而使ui執行緒被頻繁阻塞,導致畫面卡頓。這種問題一般android studio的lint靜態檢查都會報警告,平時多注意些android studio標黃的警告,有助於效能調優

當然不是任何時候都推薦使用constraintlayout的,在簡單的布局下還是建議使用linearlayout 、relativelayout,因為對於相同層級的布局下,constraintlayout的measure,layout,draw等過程會顯得更加重.

android動畫優化 Opengl渲染模式

在專案上碰到應用多個場景電流超標,經過分析是動畫導致的,主介面動畫是opengl實現的,而opengl有兩種渲染模式 連續不斷的渲染和被動渲染,應用的動畫直接是預設的連續不斷的渲染,這樣一來只要開啟了應用gpu就會一直渲染,從而造成了功耗偏高。優化的方式就是將動畫渲染模式更改為被動渲染 a.自動模式...

Android效能優化之渲染優化的8個點

大多數手機的螢幕重新整理頻率是60hz,如果在1000 60 16.67ms內沒有辦法把這一幀的任務執行完畢,系統將放棄這一幀,即發生丟幀的現象。在動畫中出現乙個丟棄幀會在平滑的體驗中看到乙個跳躍,使用者可以很容易看出來。丟幀越多,使用者感受到的卡頓情況就越嚴重。如圖某個時候我們需要用34ms的時間...

Unity 優化 渲染優化

渲染優化主要是減少gpu的壓力。1 透明效果 overdraw就是過度繪製,是指在一幀的時間內 16.67ms 畫素被繪製了多次,理論上乙個畫素每次只繪製一次是最優的,但是由於重疊的布局導致一些畫素會被多次繪製,而每次繪製都會對應到cpu的一組繪圖命令和gpu的一些操作,當這個操作耗時超過16.67...