2013-06-02 2 views
0

Я новичок в разработке Android. Я написал этот код, который рисует круг на экране, и, перемещая устройство, круг будет перемещаться по экрану. но он очень медленный на моем устройстве Nexus 7. Не могли бы вы помочь мне повысить производительность?Обновить рисунок на холсте Android слишком медленно

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(); 
    } 
} 

}

ответ

2

DonT Invalidate вызова(); в вашем OnDraw метод, назовем его только тогда, когда вы хотите, чтобы нарисовать круг в новое положение: в уставке() и перемещения() методы

+0

Все еще медленно – Pooya

+0

Вы пытались использовать трассировку http://developer.android.com/tools/help/traceview.html? – pskink

2

Вызов View.invalidate() сообщает операционной системе, чтобы перерисовать вид, вызвав View.onDraw(Canvas), поэтому вызов invalidate() в onDraw(...) означает, что устройство будет постоянно занято, перерисовывая представление. Так, как было предложено @pskink, и SampleCircle.move(...) следует вызывать View.invalidate(). Однако для максимальной эффективности вам нужно добавить допуск, так что, если ход небольшой, он не будет перерисовывать.

0

Недействительный() должен быть вызван в onSensorChanged (событие SensorEvent); и только тогда, когда происходят заметные изменения. Это, безусловно, улучшит производительность.

Смежные вопросы