Android 過度渲染及優化方法--3D效果(JakeWharton大神的scalpel)

  1. 前言

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


如有錯誤歡迎指出來,一起學習。
在這裏插入圖片描述

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