1. 程式人生 > >效能優化之過度繪製篇

效能優化之過度繪製篇

最近接到一個任務,優化專案中的過度繪製問題。提到過度繪製,腦海中會浮現出includemergeViewStub標籤,減少ViewTree的層次等等優化佈局相關,但具體怎麼進行優化,有一種無從下手的感覺。認真仔細閱讀了官方文件中關於繪製過度的講解,豁然開朗。
網上關於過度繪製的部落格也不少,但自己喜歡對自己做的功能進行總結記錄,所以抽時間寫下本篇部落格,對過度繪製進行總結,方便日後查閱。

分析工具

一.使用除錯GPU overdraw工具從視覺分析:
手機:設定->輔助功能->開發者選項->除錯GPU過度繪製->顯示過度繪製區域
這裡寫圖片描述
二.使用佈局檢查器從ViewTree結構分析:


使用Hierarchy Viewer進行ViewTree結構分析,但開啟SDK->tools發現SDK中去掉了hierarchyviewer.bat,新增了Layout Inspector進行替代。
使用方法:Android Studio點選 Tools > Android > Layout Inspector
使用Layout Inspector選擇對應程序,對相應介面就行佈局檢查,會儲存為.li檔案並開啟,借用官網的圖進行說明:
共分為三部分:
View Tree:檢視在佈局中的層次結構。
Screenshot:帶每個檢視可視邊界的裝置螢幕截圖。
Properties Table:選定檢視的佈局屬性。
這裡寫圖片描述

優化

優化過度繪製是Android效能優化的重要部分,可從以下幾方面進行優化:
一.去除無用背景:
當佈局中有多重背景時會導致檢視的過度繪製,通過刪除刪除佈局中不需要的背景來減少檢視的過度繪製。
在佈局中,如果存在多個線性佈局重疊時,可以考慮只針對最上層的佈局設定背景色,而不需要每一個佈局(例如LinearLayout)都設定背景色,過多的相同的背景色會導致過度繪製。
二.優化檢視層次結構,減少檢視層級:
優化檢視結構,減少佈局層級,可以有效的較少過度繪製,可使用Lint檢查結果進行參考幫助優化效能。
Lint使用:Android Studio的Analyze> Inspect Code使用Lint工具,檢視結果中的performance根據提示進行優化。
1.去除不需要的佈局層級:


可根據上述分析工具Layout Inspector直觀地分析檢視層次結構,減少不需要的檢視層級的繪製。
當然Lint檢測結果中也會有提示,Useless parent layout
比如:
Lint中的提示
(1)This ‘RelativeLayout’ layout or its ‘RelativeLayout’ parent is useless; transfer the ‘background’ attribute to the other view。
但只會檢測出最外層佈局且檢查不全面,具體需要根據Layout Inspector分析佈局層次,一層佈局通過新增背景,marginLeft等屬性就可實現的效果沒必要多層巢狀。
(2)Layout hierarchy is too deep
(3)Layout has too many views
對應佈局中有太深層級和太多view的警告,有時功能介面確實複雜,但我們贏儘可能地減少view的使用和佈局層次,必要時使用include,merge,viewStub進行優化。
2.TextView儘量使用CompoundDrawable::
佈局中圖示和文字的結合,這樣的效果太普通不過了,可能會習慣使用LinearLayout/ReleativeLayout下巢狀ImageView和TextView來實現佈局效果。
在LinearLayout佈局中,如果存在相鄰的ImageView和TextView,可以使用compound drawable合二為一成為一個TextView,ImageView中的圖片變成TextVIew的drawableTop/drawableLeft/drawableRight/ddrawableBottom屬性,之間的間隔使用drawablePadding屬性來代替。
比如:
Lint中的提示:
Node can be replaced by a TextView with compound drawables
但有些效果使用textview的drawable屬性並不能實現相同的效果,此時還是需要使用多個view來實現的。
3.優化巢狀layout weights:
Lint 中的提示:
Nested layout weights
巢狀layout weights時權值會被計算兩次, 改變時, 會按照比例進行改變,影響效能。此時應使用RelativeLayout或GridLayout代替LinearLayout減少沒必要的layout weights巢狀。
4.使用include,merge,viewStub標籤:
(1).include標籤共享佈局:
將通用的佈局抽取出來,獨立成一個XML檔案,在需要用到的頁面中使用include標籤引入進來,減少程式碼量,便於修改。
(2).ViewStub標籤實現延遲載入:
ViewStub是一種不可視並且大小為0的檢視,可以延遲到執行時才填充佈局資源。當ViewStub設定為可見或者被inflate之後,會填充佈局資源,ViewStub會被填充的檢視代替,和普通的檢視沒有區別。
ViewStub在需要顯示的時候才會進行檢視的填充,實現延遲載入的目的。
(3).merge標籤減少佈局層次:
當一個獨立的佈局檔案最外層是FrameLayout且這個佈局不需要設定背景等屬性時或者當前佈局是另外一個佈局的子佈局時,可以使用merge來減少佈局的層次。
5.在自定義view的onDraw()中過度繪製問題。
在自定義view的onDraw中,如果涉及到重疊的繪製view時,可以考慮利用區域性繪製避免過度繪製。
考慮到效率和效能問題,介面是有一定重新整理頻率的,每一次重新整理都會呼叫View的onDraw方法,而View提前繪製就是在onDraw中進行,避免在onDraw建立物件,避免在onDraw進行繪製,應在建構函式中畫好,交給onDraw。

總結