王剛---- UIレンダリングのパフォーマンス最適化の最適化(CPUとGPUの原則、最適化、レイアウトの最適化をオーバードロー)

まず:GPUとCPUのワークフローとオーバードロー
、我々はインターフェイスを参照してください、インタフェースのすべての塗装のものは、GPUによって行われますが、どのようにペイントすると、CPUによって行われます。端的に言えば、CPUは図面を算出する方法で、GPUは、画面を描画する方法で、CPUはGPUになります。
私たちの最適化は、2つのポイントに分けられます:(1)CPU:時間のオブジェクトにXMLを変換する削減、(2)GPU:再描画の時間短縮、
オーバードロー何を?
GPUレンダリングプロセスは、ちょうどしっくいとして、層ごとに、16msのブラシです。これは、層またはどちらで覆われた画像の現象は、不必要な廃棄物を生じる、下部に描画されることになります。
あなたはUIのレンダリングの原則を理解していない場合は、こちらをjabbed アンドロイドレイアウトレンダリングプロセス
ビュー過度の描画方法を:
開発者向けのオプションは、 - >ハードウェアは--->デバッグGPUオーバードローをレンダリング加速。
私たちは第二の選択、第三は、色盲の選択である、3つのオプションがあります。第二を選択した後、あなたは、私たちの携帯電話がカラフルになっています。
ここに画像を挿入説明
活動時間は、1ページのみ場合、画面が白なので、上の水色を見えるものの層が、この層のオーバードロー(1xOverDraw)と呼ばれ、追加、および。5層以上(4xOverdraw)は赤色で表示されます。
II:最適化過剰延伸(主にGPUの作業負荷を低減する)
最適化1 :: XMLレイアウトや背景色windowBackgroud競合
溶液は、GetWindow()setBackgroundDrawable(NULL); nullに設定。または黒と白の画面設定を解決するには、物品をモデルにした方法。
最適化2:レイアウトを任意の背景、特に根のレイアウトを設定していません。
最適化3:ImageViewの背景色を設定しないでください。iv_imageView.setBackgroundColor(Color.TRANSPARENT);
任意のパフォーマンスを消費しませandroid.R.color.transparentに注意してください。
次のように`コードです

 if (chat.getAuthor().getAvatarId() != 0) {
            Picasso.with(getContext()).load(chat.getAuthor().getAvatarId()).into(
                    chat_author_avatar);
            chat_author_avatar.setBackgroundColor(Color.TRANSPARENT);
        } else {
            Picasso.with(getContext()).load(android.R.color.transparent).into(
                    chat_author_avatar);
            chat_author_avatar.setBackgroundColor(chat.getAuthor().getColor());
        }

コントロールは、透明または不透明にするかどうか、CPUは、コンピューティングを行くだろうが、透明設定、それはGPUレンダリングには行きません。不透明な時間を設定し、我々は、GPUコンピューティングに行きます。これは時間のGPUを節約できます。
最適化4:図に示すようなライセンスカードなどのある場合においては、確かに、問題が発生重なります。
ここに画像を挿入説明
私たちは前にコードを最適化するために見て
DroidCardクラス

package com.example.android.mobileperf.render;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
//扑克牌实体类
public class DroidCard {
    //x坐标,y坐标我省略了。
    public int x;
    public int width;
    public int height;
	//一张扑克牌,是由一张图片构成的。
    public Bitmap bitmap;

    public DroidCard(Resources res,int resId,int x){
        this.bitmap = BitmapFactory.decodeResource(res,resId);
        this.x = x;
        this.width = this.bitmap.getWidth();
        this.height = this.bitmap.getHeight();
    }

}

カスタムDroidCardsView

package com.example.android.mobileperf.render;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class DroidCardsView extends View {

    //图片与图片之间的间距
    private int mCardSpacing = 150;
    //图片与左侧距离的记录
    private int mCardLeft = 10;
    //存储图片
    private List<DroidCard> mDroidCards = new ArrayList<DroidCard>();

    private Paint paint = new Paint();

    public DroidCardsView(Context context) {
        super(context);
        initCards();
    }

    public DroidCardsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initCards();
    }


     /**
     * 初始化卡片集合,初始化三张图片,三张图片坐标有一个偏移
     */
    protected void initCards(){
        Resources res = getResources();
        mDroidCards.add(new DroidCard(res, R.drawable.alex,mCardLeft));

        mCardLeft+=mCardSpacing;
        mDroidCards.add(new DroidCard(res, R.drawable.claire,mCardLeft));

        mCardLeft+=mCardSpacing;
        mDroidCards.add(new DroidCard(res, R.drawable.kathryn,mCardLeft));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
		//因为三张图片坐标有偏移,所以绘制list的时候三张图片会一张一张向右摆放。
        for (DroidCard c : mDroidCards) {
            drawDroidCard(canvas,c);
        }

        invalidate();
    }

    private void drawDroidCard(Canvas canvas, DroidCard c) {
        canvas.drawBitmap(c.bitmap,c.x,0f,paint);
    }

}

私たちは、レイアウトを使用します

<?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="@android:color/white"
    android:orientation="vertical">
//自定义控件
    <com.example.android.mobileperf.render.DroidCardsView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

ディスプレイが、それは効果を実現することができますが、UIは深刻なオーバーラップを描くようにします。どのようにそれを解決するには?
私たちは、キャンバスの一部が伐採表示することができます。どこでカットを描画します。キャンバスは非常に大きいので、それを扱う以上配置しないでしょう。GPUは、余分なスペースを気にしません。
私たちは、クラスDroidCardsViewを変更します

package com.example.android.mobileperf.render;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class DroidCardsView extends View {

    //图片与图片之间的间距
    private int mCardSpacing = 150;
    //图片与左侧距离的记录
    private int mCardLeft = 10;
    //存储图片
    private List<DroidCard> mDroidCards = new ArrayList<DroidCard>();

    private Paint paint = new Paint();

    public DroidCardsView(Context context) {
        super(context);
        initCards();
    }

    public DroidCardsView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initCards();
    }



    /**
     * 初始化卡片集合,初始化三张图片,三张图片坐标有一个偏移
     */
    protected void initCards(){
        Resources res = getResources();
        mDroidCards.add(new DroidCard(res, R.drawable.alex,mCardLeft));

        mCardLeft+=mCardSpacing;
        mDroidCards.add(new DroidCard(res, R.drawable.claire,mCardLeft));

        mCardLeft+=mCardSpacing;
        mDroidCards.add(new DroidCard(res, R.drawable.kathryn,mCardLeft));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
		   //因为三张图片坐标有偏移,所以绘制list的时候三张图片会一张一张向右摆放。
          for (DroidCard c : mDroidCards) {
            drawDroidCard(canvas,c);
           }
         *
         */
		//注意size-1,如果有三张图,我们只画两张,最后一张单独处理就行了。
        for (int i = 0; i < mDroidCards.size() - 1; i++){
            drawDroidCard(canvas, mDroidCards,i);
        }
        drawLastDroidCard(canvas,mDroidCards.get(mDroidCards.size()-1));

        invalidate();
    }

//    private void drawDroidCard(Canvas canvas, DroidCard c) {
//        canvas.drawBitmap(c.bitmap,c.x,0f,paint);
//    }

    /**
     * 绘制最后一个DroidCard
     * @param canvas
     * @param c
     */
    private void drawLastDroidCard(Canvas canvas,DroidCard c) {
        canvas.drawBitmap(c.bitmap,c.x,0f,paint);
    }

    /**
     * 绘制DroidCard,只绘制出裁剪出来的一部分
     * @param canvas
     * @param mDroidCards
     * @param i 第几张图片
     */
    private void drawDroidCard(Canvas canvas,List<DroidCard> mDroidCards,int i) {
        DroidCard c = mDroidCards.get(i);
        //保存当前画布
        canvas.save();
        //画布裁剪一个矩形出来,参数的意思是左上右下
        canvas.clipRect((float)c.x,0f,(float)(mDroidCards.get(i+1).x),(float)c.height);
        canvas.drawBitmap(c.bitmap,c.x,0f,paint);
        //画布还原
        canvas.restore();
    }
}

第三:布局的优化(主要减少CPU的工作量)
在sdk中有一个工具可以帮助我们做性能优化,D:\sdk\tools\bin目录下的uiautomatorviewer.bat工具。
介绍下android studio中的性能优化工具-Layout Inspector性能优化工具的使用
首先在android studio中找到它。
ここに画像を挿入説明
选择你要查看的进程,一般会有很多进程,我们这里因为我只有一个项目,所以只有一个进程。
ここに画像を挿入説明
查看所在进程的布局文件
ここに画像を挿入説明
navigationBarBackground是我们的导航栏,statusBarBackgroud是最上面的状态栏。整个xml布局结构可以在左侧清楚的看到。
另外在D:\sdk\tools下的monitor.bat中,点击Hierarchy Viewer中可以看到Hierarchy Viewer。其效果与Layout Inspector是类似的。Hierarchy Viewer中有三个点:绿色表示该View的此项性能比该View Tree中超过50%的都要快;黄色表示该View的此项性能比该View Tree中超过50%的都要慢;红色表示该View的此项性能是View Tree中最慢的。
优化1::能在一个平面显示的内容,尽量只用一个容器。不要过多的布局嵌套
优化2:尽可能把相同的容器合并merge
当是父亲独生子的时候,可以使用merge合并,这样在树中会少一层,少一层CPU计算的东西就少了一份。
ここに画像を挿入説明
LinearLayout所在的布局代码修改跟标签为merge





組み合わされた場合には、ID属性のLinearLayoutを持つことができないことに注意してください
最適化3:エネルギー処理コードの再利用は、CPUの重複を減らすことができます。コードの再利用を可能な限り再利用することができ、物事は繰り返し書いて、繰り返し書く行くことができる再利用しないCPUが計算するのと同じことを繰り返すことになります。たとえば、各ページがToorBar使用されています。
最初にロードされ、我々はレイアウトが含まれる場合は、CPUからGPUに、このプロセスは完了です。GPUコンピューティングCPUに良い実行した後。GPUは、これらの事は、キャッシング、必要性がこのように計算するために二回目を行いませんCPU内部キャッシュを実行するためにGPUから取り出して、次の時間を行う使用します。

おすすめ

転載: blog.csdn.net/qczg_wxg/article/details/89741141