0

カスタムスライドコントロールを作成しています。ボリューム ホイールのようなもので、回転方向に応じて一部の値が増減します。これには2つの問題があります:

  1. 性能は確かに低い
  2. ガベージ コレクターは、何度も何度もトリガーされます。

まあ、私は何か間違ったことをしていると確信しているので、ライトをください。

2.1 (eclaire) SDK で Android グラフィックスを使用しています。

これは、私のアクティビティから呼び出しているビューのコードです:

public class DrawingView extends View {

private Paint p;
Bitmap bitmap;
Context mContext;
Canvas canvas;
private float sweepAngle;
private int _height;
private int _width;
private float lastAngle;
private int percent;

public DrawingView(Context context) {
    super(context);
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    this.set_Width(display.getWidth());
    this.set_Height(display.getHeight());
    this.setSweepAngle(10);
    mContext = context;
    p = new Paint();
    p.setAntiAlias(true);

}

protected int getAngleFromLocation(Point location){
    int finalAngle = (int) (Math.atan2(location.y - 200, location.x - 200) * (180 / Math.PI));
    return finalAngle;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),Bitmap.Config.ARGB_8888);
    this.canvas = new Canvas(bitmap);
    RectF rectF = new RectF();
    rectF.set(20, 20, this.get_Widtt() - this.get_Widtt()/10, this.get_Widtt() - this.get_Widtt()/10);
    canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
    //invalidate();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    double increment = 3.6;
    Point touchLocation = new Point();
    touchLocation.x = (int)event.getX();
    touchLocation.y = (int)event.getY();
    canvas.drawBitmap(bitmap = Bitmap.createBitmap(canvas.getWidth(),canvas.getHeight(),Bitmap.Config.ARGB_8888),event.getX(), event.getY(),null );
    switch (event.getAction())
    { 
        case MotionEvent.ACTION_DOWN: 
            lastAngle = this.getAngleFromLocation(touchLocation);
            System.out.println("ACTION_DOWN");
            break;

        case MotionEvent.ACTION_MOVE:
            System.out.println("ACTION_MOVE");
            int currentAngle = this.getAngleFromLocation(touchLocation);
            System.out.println("CURRENT ANGLE: " + currentAngle); 
            if (currentAngle > lastAngle || (currentAngle == 1 && lastAngle == 359)) {
                percent += increment;
            } else if (currentAngle < lastAngle) {
                percent -= increment;
            }
            if (percent > 360) {
                percent = 360;
            } else if (percent < 0) {
                percent = 0;
            }
            lastAngle = currentAngle;
             this.setSweepAngle(percent);
             //Write the label
             //int realPercent = percent*100/360;
            System.out.println("PERCENT: "+percent); 
            break;

        case MotionEvent.ACTION_UP:
            break;
    }
    return true;
}
}
4

2 に答える 2

3

フレームごとに新しいビットマップを作成する必要はありません。実際、onDraw() でオブジェクトを割り当てないようにする必要があります。

これを試して:

private RectF mRectF = new RectF();

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLACK);
    mRectF.set(20, 20, this.get_Widtt() - this.get_Widtt() / 10, this.get_Widtt() - this.get_Widtt() / 10);
    canvas.drawArc(rectF, 180, this.getSweepAngle(), true, p);
}

onTouchEvent の canvas.drawBitmap() への呼び出しも削除します。

于 2012-09-24T13:18:30.997 に答える
0

非常に時間がかかり、GC を非常にトリガーしているのは、ビットマップ/キャンバスの作成である可能性が最も高いです。onDraw()特に、オブジェクトの作成はできるだけ少なくしたいと考えていますonTouchEvent()。それを一度呼び出される別のメソッドに移動して、各フレームで同じビットマップを再利用できない理由はありますか? 渡す値createBitmap()は静的であるように見えるため、問題にはなりません。

于 2012-09-24T13:19:14.663 に答える