性能優化之View渲染

在這裏插入圖片描述
首先我們需要知道以下幾點

1 view的基本繪製流程(ViewGroup和View)

2 view的重複繪製原因

3 怎麼減少重複繪製

View的基本繪製流程

 做過Android開發的同學都知道,View繪製分爲三個階段:測量、佈局和繪製。
    1. 測量即measure階段:測量主要用到measureSpec這個類,其實是一個32位的int值,其中高2位表示view的測量模式,低30位表示view測量大小,兩者共同組合成了view的大小,之所以這麼做,是採用位運算可以提高效率,每個view的大小實際上是通過自身視圖和父視圖決定的。
    2. layout即擺放位置階段:爲整個view樹上的view擺放位置
    3.draw階段:根據前兩個階段得到的參數值,用paint在cances將視圖顯示在屏幕上。

這裏摘抄網上的一張繪製流程圖:
在這裏插入圖片描述

從圖中可以出看出當一個頁面顯示出來時,繪製流程是從performTraversals()方法開始的,這邊又涉及到了view的層級關係,再放張圖
在這裏插入圖片描述
當一個Activity創建時,會將一個window和activity關聯,所以window的數量和activity是一致的,該處的window即phoneWindow,是window的唯一子類,並且還會創建一個DecoView和ViewRootImpl,兩者建立聯繫,再從ViewRootImpl的performTraversals()開始繪製,該方法會調用performMeasure() 進行測量子view,一開始是頂層viewGroup,然後依次調用到view,再到viewGroup,如此反覆,就完成了一個view的繪製。

調用結束performMeasure(),會依次再調用performLayout(),performDraw()

三者主要作用如下

meausure過程:

主要負責測量,如果單個View,直接measuere測量,如果是viewGroup,需要重寫onMeasure方法,對子視圖遍歷測量

layout過程:

在View視圖座標下(x軸朝右,y軸朝下),根據left,top,right,bottom進行位置的擺放,如果是viewGroup,同樣需要遍歷擺放

draw過程:

繪製背景

如果視圖有漸變,做一些初始化工作

繪製視圖本身,即調用onDraw()方法,改方法是個空方法,如果是ViewGroup,無需實現該方法,因爲容器是有多個子view組成的,所以只需要遍歷ViewGroup,讓子view完成自己繪製即可

如果需要,開始繪製漸變框

繪製滾動條

View的重複繪製原因以及優化

我們知道,Android系統是每隔16ms發送一次信號,進行刷新UI操作,因此我們必須在16ms之內將頁面繪製完成,從而保證頁面流暢

通過上面view繪製流程的分享,view繪製優化分爲內部和外部。

內部優化:
即view自身繪製花費的時間,繪製流程我們無法干預,但是我們可以減少內部繪製的時間,如下圖

在這裏插入圖片描述
外部優化
在這裏插入圖片描述
其實平時我們平時做的比較多的是外部優化,比如需要將一個TextView和ImgView一起顯示時,無需用一個layout將兩個view組合包在一起,可以考慮使用TextView的drawRight屬性設置圖片

具體見下圖

在這裏插入圖片描述
劃重點

1.佈局嵌套過於複雜

儘可能的使用Relativelayout來減少層級,使View趨於扁平化

在Linearlayout和RelativeLayout兩次深度差不多的情況下使用LinearLayout,因爲Reltive由於存在依賴關係,需要測量兩次,而LinearLatout存在orientation屬性

靈活使用merge,include標籤

層級特別深時,儘量少使用權重wight,因爲也會導致二次測量

選用合適的佈局可以借鑑下圖

在這裏插入圖片描述

2.VIew的頻繁渲染

頻繁動態的改變寬高,調用setlayoutParams會執行requeatlayout,導致頻繁繪製

當需要刷新UI時,如果不需要重新測量時,UI線程直接使用invalidate,非UI線程使用postinvalidate,而不要使用requestLayout,因爲該方法會重新走一遍繪製流程

使用viewStub進行懶加載

3.UI進行網絡操作,4.0以後已經不允許

UI刷新時異步進行,使用handler

4.代碼邏輯冗餘複雜,例如多層遍歷

可以使用合適的數據結構,例如接口返回字段是map,並且需要排序時,可以使用TreeMap接收,減少排序遍歷

5.頻繁觸發gc,影響頁面渲染,因爲gc線程優先級高於UI線程

不要頻繁生成對象,比如字符串拼接時,儘量使用StringBuilder操作,不要進行+號拼接字符串

6.View過度繪製

總結:View繪製優化是性能優化中重要的一環,當業務越來越龐大,頁面愈加複雜時,尤其需要進行view繪製的性能優化

在這裏插入圖片描述
更精彩內容,大家可以關注我的微信公衆號
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章