- 前言
Android 中的過度繪製是指同一個像素被繪製多次,從繪製性能角度講,同一像素點被繪製的次數當然越少越好,這樣有利於減輕 GPU 的工作壓力,事實上,在具體開發過程中 ,不可避免的可能會出現過度繪製,這裏,Android 系統本身在開發者選項裏已經提供了一個選項開關 Debug GPU overdraw(調試 GPU 過度繪製),用於檢測 App 的過度繪製, 只要打開這個開關,App 界面就會在不同的界面區域根據像素的繪製次數顯示出不同的顏色。
2.基本介紹
1)打開手機的過度繪製開關。
操作順序:【設置—>更多設置—>開發者模式—>調試GPU過度繪製—>顯示過度繪製區域】
最後打開後如圖所示:
2)顏色的標識
從好到差:藍-綠-淡紅-紅,具體表現爲:
1.藍色1x過度繪製
2.綠色2x過度繪製
3.淡紅色3x過度繪製
4.紅色超過4x過度繪製
官方對過度渲染的圖片介紹:
3)驗收標準
1.控制過度繪製爲2x
2.不允許存在4x過度繪製
3.不允許存在面積超過屏幕1/4區域的3x過度繪製(淡紅色區域)
3.優化措施
由於公司項目不能拿來開放,自己寫了個類似的登陸界面,如下所示:
可以看到,因爲該界面佈局簡單,但是簡單的界面也出現了紅色,說明出現了過度渲染,下面我們就解決掉當前界面的過度渲染問題。
1)利用DDMS觀察其他應用佈局實現方式
具體使用方法前面已經介紹過:http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51331006
缺點:只能看清楚層次,不能知道具體什麼原因導致過度渲染。
2)JakeWharton大神的scalpel
github連接:https://github.com/JakeWharton/scalpel
將當前頁面的佈局3D化,有點像xcode上的view ui hierarchy工具,效果如圖所示:
優點:
1.可以很方便的在頁面上看到佈局的id,從而快速找出對應出問題的控件。
2.支持3D跟縮放功能,可以清晰看到佈局文件的層次結構,跟引起過度渲染的層次或者對應的佈局塊,非常靈活。
使用步驟:
1.build.gralde中加入如下代碼:
compile 'com.jakewharton.scalpel:scalpel:1.1.2'
2.使用的時候你的layout根節點必須是 ScalpelFrameLayout
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View mainView = getLayoutInflater().inflate(R.layout.activity_main,null);
ScalpelFrameLayout scalpelFrameLayout = new ScalpelFrameLayout(this);
scalpelFrameLayout.addView(mainView);
scalpelFrameLayout.setLayerInteractionEnabled(true);
scalpelFrameLayout.setDrawIds(true);
setContentView(scalpelFrameLayout);
initView();
loadData();
}
3.其他方法
開啓3D效果 : setLayerInteractionEnabled(boolean).
顯隱DrawViews:setDrawViews(boolean).
顯隱 view ID: setDrawIds(boolean).
修改邊框的顏色和陰影 setChromeColor(int) and setChromeShadowColor(int).
配置完成後,運行項目,當前頁面則會呈現上圖的效果。通過觸摸頁面,可以清楚的看到每個控件的id以及佈局層次。從上圖可以看到,過度渲染呈現出來的綠色,紅色都是成塊的,我這邊LinearLayout沒有定義id,如果定義id就更容易看出來,成塊的都是LinearLayout佈局,也就是背景顏色設置重複造成頁面過度渲染。
4.查看xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@mipmap/service_top_bg" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#ffffff"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="用戶名"
android:textSize="20sp" />
<EditText
android:id="@+id/user_name"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="12dp"
android:background="@null"
android:hint="請輸入用戶名"
android:textSize="20sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="密碼"
android:textSize="20sp" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="12dp"
android:background="@null"
android:hint="請輸入密碼"
android:textSize="20sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="登錄" />
</LinearLayout>
</LinearLayout>
第5,17,23都設置了背景顏色,而且都是LinearLayout,這樣對於26行的textview來說,已經多了三層背景色,再加上自身內容的渲染,已經四層,肯定顯示紅色,也對應了3D模型顯示的結果,我們的做法是去掉沒有必要的背景顏色。更改後的xml文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@mipmap/service_top_bg" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="用戶名"
android:textSize="20sp" />
<EditText
android:id="@+id/user_name"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="12dp"
android:background="@null"
android:hint="請輸入用戶名"
android:textSize="20sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="密碼"
android:textSize="20sp" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="12dp"
android:background="@null"
android:hint="請輸入密碼"
android:textSize="20sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000000" />
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="登錄" />
</LinearLayout>
</LinearLayout>
5.效果對比
優化前:
優化後:
這樣頁面已經沒有了紅色,都是藍色,已經非常好了。可見,手機GPU過度繪製功能打開後再配合JakeWharton大神的Scalpel插件可以非常有效地定位過度繪製問題,完全可以代替SDK的Hierarchy UI功能,讓開發者更好的優化佈局層次。
4.優化總結
1.根佈局的背景色謹慎設置,避免無效背景色。
2.減少佈局層次,雖然佈局層次不影響GPU過度渲染,但是複雜的嵌套勢必會影響xml加載效率,也會增加像素點多次繪製的機率。
5.源碼下載地址
源碼下載地址:http://download.csdn.net/detail/dfskhgalshgkajghljgh/9719779
如有錯誤歡迎指出來,一起學習。