まず: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から取り出して、次の時間を行う使用します。