在我們已經透過 Layout 的優化來減少 UI 的階層,接下來要往繪製的效能來優化。每一次的繪製都需要成本,所以如果可以減少繪製的步驟,就可以提升效率。
當一個 frame 的同一個 pixel 被繪製了多次,就叫重複繪製 (Overdraw)。例如下圖的範例,有一個黃色及藍色的個矩形 View,黃色的部分疊在藍色上面。Android 將會對藍色的View與黃色的 View 各做一次繪製。那麼中間的區塊就是一個重複繪製,因為藍色與黃色的重疊部分繪製了 2 次,多繪製的藍色是使用者看不到的。
你可能會看到有些中文把 Overdraw 翻譯為過度繪製。其實我們倒不能說這樣就叫過度,這種情況其實就是重複了,同一個 Frame 重複繪製了。既然有重複繪製,就代表其中一個畫面被蓋掉了,使用者也就看不到。對一個看不到的地方進行繪製,當然也就是一種浪費。
減少重複繪製的方式有:
View 的繪製有 3 個步驟 :Measure、Layout、Draw,而Draw的步驟有:
一個常見的錯誤就是把每個 View 都設定了背景色。假設 App 的每個畫面背景顏色都是一樣的,你可以直接在 Themes 使用主題來設定統一的背顏色,就不需要在每個 Activity 裡的 Layout 去設定一樣的背景。即便有時為了好看的排版使用了多層的 Layout 結構,也要注意不要設定了重複的背景色。
在使用元件時,如果元件本身就有會覆蓋在背景上的設定,就不需再設定背景。例如 ImageView 已經在 src
設定了圖片,就不需要在設定 background
了。
<ImageView
android:id="@+id/imageView"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/ic_launcher"
android:background="@color/teal_200"/>
Layout 越複雜,效能就可能越差。但多個 ConstraintLayout 或 LinearLayout 儘管都需要依照裡面的所有元件來測量位置,並不會造成太大的效能問題,會造成效能問題的是巢狀的結構。巢狀的結構將使得測量寬高變得複雜並造成重疊的 UI,也就是繪製了很多看不到的東西。減少重疊的 UI 也就能減少重複繪製。只有在你用了複雜的巢狀時會有效能問題。
如果我們將一個 View 設定了透明度,Android 的處理方式會是先繪製原有像素,接著再將其透明化繪製一次。所以如果非必要,就應該減少使用透明度來減少重複繪製。例如要設定一個 Textview 的為 70% 透明的黑色,不應該將文字顏色設定為黑色,再設定 View 的 alpha 為 0.7。而是直接使用透明度 70% 的黑色顏色。
直接從 color 設定透明度70%的黑色
<TextView
android:layout_width="wrap_content"
android:textColor="#B2000000"
android:layout_height="wrap_content"/>
設定顏色黑色,alpha 值為 70%,即為顏色#b2000000
。
了解如何減少重複繪製後,下一篇就來看如何用工具查看是否存在重複繪製。
參考:
https://developer.android.com/topic/performance/rendering/overdraw