在Android画布上刷新绘图太慢了

时间:2013-06-02 17:13:06

标签: android performance android-sensors

我是android开发的新手。我写了这段代码,在屏幕上绘制一个圆圈,通过移动设备,圆圈将在屏幕上移动。但是我的Nexus 7设备速度非常慢。你能帮助我提高表现吗?

public class MainActivity extends Activity implements SensorEventListener {

public static SensorManager mSensorManager;
public static Sensor accelerometer;
public static Sensor magnetometer;
public static float[] mAccelerometer = null;
public static float[] mGeomagnetic = null;
private SampleCircle sampleCircle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RelativeLayout layout = (RelativeLayout) findViewById(R.id.mainForm);
    sampleCircle = new SampleCircle(this);

    layout.addView(sampleCircle);


    layout.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            sampleCircle.setPoint(motionEvent.getX(), motionEvent.getY());
            return false;
        }
    });

    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}

@Override
protected void onResume() {
    super.onResume();

    mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
    mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_GAME);
}

@Override
protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this, accelerometer);
    mSensorManager.unregisterListener(this, magnetometer);
}

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        mAccelerometer = event.values;
    }

    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
        mGeomagnetic = event.values;
    }

    if (mAccelerometer != null && mGeomagnetic != null) {
        float R[] = new float[9];
        float I[] = new float[9];
        boolean success = SensorManager.getRotationMatrix(R, I, mAccelerometer, mGeomagnetic);

        if (success) {
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);
            // at this point, orientation contains the azimuth(direction), pitch and roll values.
            double azimuth = 180 * orientation[0] / Math.PI;
            double pitch = 180 * orientation[1] / Math.PI;
            double roll = 180 * orientation[2] / Math.PI;

            sampleCircle.move((float) Math.floor(pitch), (float) Math.floor(roll));

        }
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void onAccuracyChanged(Sensor sensor, int i) {
    System.out.println("Acc");
}

private class SampleCircle extends View {
    private Paint p = new Paint();
    {
        p.setColor(Color.RED);
        p.setStyle(Paint.Style.FILL);
    }
    private float y;
    private float x;

    public SampleCircle(Context context, float x, float y) {
        super(context);
        this.y = y;
        this.x = x;
    }

    public SampleCircle(Context context) {
        super(context);

    }

    public void setPoint(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public void move(float x, float y) {
        this.x -= x;
        this.y -= y;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(x, y, 50, p);
        invalidate();
    }
}

}

3 个答案:

答案 0 :(得分:2)

不要调用invalidate();在onDraw方法中,只有在想要在新位置绘制圆时才调用它:在setPoint()和move()方法中

答案 1 :(得分:2)

调用View.invalidate()会通过调用View.onDraw(Canvas)告诉操作系统重绘视图,因此调用invalidate()中的onDraw(...)表示设备将永久忙于重新绘制视图。因此,正如@pskink所建议的那样,View.invalidate()应该从SampleCircle.setPoint(...)SampleCircle.move(...)方法调用。但是,为了获得最大效率,您需要添加一个容差,这样如果移动很小,就不会重新绘制。

答案 2 :(得分:0)

应在onSensorChanged(SensorEvent事件)中调用invalidate();并且只有在发生明显变化时。这肯定会提高性能