Di Android, jika Anda ingin menghidupkan objek dan membuatnya memindahkan objek dari location1 ke location2, API animasi menentukan lokasi perantara (tweening) dan kemudian mengantri ke utas utama operasi pemindahan yang tepat pada waktu yang tepat menggunakan penghitung waktu . Ini berfungsi dengan baik kecuali bahwa utas utama biasanya digunakan untuk banyak hal lain - melukis, membuka file, menanggapi input pengguna dll. Timer yang antri sering dapat ditunda. Program yang ditulis dengan baik akan selalu mencoba melakukan sebanyak mungkin operasi di utas latar (non utama) namun Anda tidak dapat selalu menghindari menggunakan utas utama. Operasi yang mengharuskan Anda beroperasi pada objek UI selalu harus dilakukan di utas utama. Juga, banyak API akan menyalurkan operasi kembali ke utas utama sebagai bentuk keselamatan utas.
Tampilan semuanya digambar pada utas GUI yang sama yang juga digunakan untuk semua interaksi pengguna.
Jadi jika Anda perlu memperbarui GUI dengan cepat atau jika rendering terlalu banyak waktu dan memengaruhi pengalaman pengguna, gunakan SurfaceView.
Contoh gambar rotasi:
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);
}
}
}
}
}
aktivitas:
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));
}
}