按照以下步驟打開Show GPU Overrdraw的選項(xiàng):設(shè)置 -> 開發(fā)者選項(xiàng) -> 調(diào)試GPU過度繪制 -> 顯示GPU過度繪制
每個顏色的說明如下:
原色:沒有過度繪制
藍(lán)色:1 次過度繪制
綠色:2 次過度繪制
粉色:3 次過度繪制
紅色:4 次及以上過度繪制
觀察app里的繪制情況,然后可以使用Hierarchy Viewer來進(jìn)行優(yōu)化。
常用解決套路
通過以上的工具找到問題之后就是如何去處理了,下面總結(jié)了一些常用套路
套路一:去掉window的默認(rèn)背景
當(dāng)我們使用了Android自帶的一些主題時,window會被默認(rèn)添加一個純色的背景,這個背景是被DecorView持有的。當(dāng)我們的自定義布局時又添加了一張背景圖或者設(shè)置背景色,那么DecorView的background此時對我們來說是無用的,但是它會產(chǎn)生一次Overdraw,帶來繪制性能損耗。去掉window的背景可以在onCreate()中setContentView()之后調(diào)用
getWindow().setBackgroundDrawable(null);
或者在theme中添加
android:windowbackground="null";
套路二:去掉其他不必要的背景
有時候?yàn)榱朔奖銜冉oLayout設(shè)置一個整體的背景,再給子View設(shè)置背景,這里也會造成重疊,如果子View寬度mach_parent,可以看到完全覆蓋了Layout的一部分,這里就可以通過分別設(shè)置背景來減少重繪。再比如如果采用的是selector的背景,將normal狀態(tài)的color設(shè)置為“@android:color/transparent”,也同樣可以解決問題。這里只簡單舉兩個例子,我們在開發(fā)過程中的一些習(xí)慣性思維定式會帶來不經(jīng)意的Overdraw,所以開發(fā)過程中我們?yōu)槟硞€View或者ViewGroup設(shè)置背景的時候,先思考下是否真的有必要,或者思考下這個背景能不能分段設(shè)置在子View上,而不是圖方便直接設(shè)置在根View上。
套路三:clipRect的使用
我們可以通過canvas.clipRect()來 幫助系統(tǒng)識別那些可見的區(qū)域。這個方法可以指定一塊矩形區(qū)域,只有在這個區(qū)域內(nèi)才會被繪制,其他的區(qū)域會被忽視。這個API可以很好的幫助那些有多組重疊 組件的自定義View來控制顯示的區(qū)域。同時clipRect方法還可以幫助節(jié)約CPU與GPU資源,在clipRect區(qū)域之外的繪制指令都不會被執(zhí)行,那些部分內(nèi)容在矩形區(qū)域內(nèi)的組件,仍然會得到繪制。
套路四:ViewStub
ViewStub稱之為“延遲化加載”,在很多數(shù)情況下,程序無需顯示ViewStub所指向的布局文件,只有在特定的某些較少條件下,此時ViewStub所指向的布局文件才需要被inflate,且此布局文件直接將當(dāng)前ViewStub替換掉,具體是通過viewStub.infalte()或viewStub.setVisibility(View.VISIBLE)來完成;常見的比如網(wǎng)絡(luò)加載布局
套路五:Merge標(biāo)簽
MMerge標(biāo)簽可以干掉一個view層級。Merge的作用很明顯,但是也有一些使用條件的限制。有兩種情況下我們可以使用Merge標(biāo)簽來做容器控件。第一種子視圖不需要指定任何針對父視圖的布局屬性,就是說父容器僅僅是個容器,子視圖只需要直接添加到父視圖上用于顯示就行。另外一種是假如需要在LinearLayout里面嵌入一個布局(或者視圖),而恰恰這個布局(或者視圖)的根節(jié)點(diǎn)也是LinearLayout,這樣就多了一層沒有用的嵌套,無疑這樣只會拖慢程序速度。而這個時候如果我們使用merge根標(biāo)簽就可以避免那樣的問題。另外Merge只能作為XML布局的根標(biāo)簽使用,當(dāng)Inflate以開頭的布局文件時,必須指定一個父ViewGroup,并且必須設(shè)定attachToRoot為true。不常用的UI被設(shè)置成GONE,比如異常的錯誤頁面,如果有這類問題,我們需要用標(biāo)簽,代替GONE提高UI性能。,畢竟visible/gone是會引起布局重繪的
套路六:inlcude標(biāo)簽
標(biāo)簽?zāi)軌蛑赜貌季治募?/p>
還有可以嘗試使用ConstraintLayout也可以大大減少布局的嵌套,提高UI性能等。