En Android, si desea animar un objeto y hacer que mueva un objeto de ubicación1 a ubicación2, la API de animación calcula las ubicaciones intermedias (interpolación) y luego pone en cola en el hilo principal las operaciones de movimiento apropiadas en los momentos apropiados usando un temporizador . Esto funciona bien, excepto que el hilo principal generalmente se usa para muchas otras cosas: pintar, abrir archivos, responder a las entradas del usuario, etc. Un temporizador en cola a menudo se puede retrasar. Los programas bien escritos siempre intentarán realizar tantas operaciones como sea posible en subprocesos en segundo plano (no principales), sin embargo, no siempre puede evitar usar el subproceso principal. Las operaciones que requieren que opere en un objeto UI siempre deben realizarse en el hilo principal. Además, muchas API canalizarán las operaciones al hilo principal como una forma de seguridad de hilo.
Las vistas se dibujan en el mismo hilo GUI que también se usa para toda la interacción del usuario.
Entonces, si necesita actualizar la GUI rápidamente o si el renderizado toma demasiado tiempo y afecta la experiencia del usuario, use SurfaceView.
Ejemplo de imagen de rotación:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
drawThread = new DrawThread(getHolder(), getResources());
drawThread.setRunning(true);
drawThread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
drawThread.setRunning(false);
while (retry) {
try {
drawThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
class DrawThread extends Thread{
private boolean runFlag = false;
private SurfaceHolder surfaceHolder;
private Bitmap picture;
private Matrix matrix;
private long prevTime;
public DrawThread(SurfaceHolder surfaceHolder, Resources resources){
this.surfaceHolder = surfaceHolder;
picture = BitmapFactory.decodeResource(resources, R.drawable.icon);
matrix = new Matrix();
matrix.postScale(3.0f, 3.0f);
matrix.postTranslate(100.0f, 100.0f);
prevTime = System.currentTimeMillis();
}
public void setRunning(boolean run) {
runFlag = run;
}
@Override
public void run() {
Canvas canvas;
while (runFlag) {
long now = System.currentTimeMillis();
long elapsedTime = now - prevTime;
if (elapsedTime > 30){
prevTime = now;
matrix.preRotate(2.0f, picture.getWidth() / 2, picture.getHeight() / 2);
}
canvas = null;
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(picture, matrix, null);
}
}
finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
actividad:
public class SurfaceViewActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MySurfaceView(this));
}
}