Tuesday 25 May 2010

Android SurfaceView, run in Thread with sleep()

Further works on the last exercise "Android SurfaceView", a call to sleep(500) is introduced in run() of the thread, such that the onDraw() will be called in half second.

In this exercise, there is a point on the screen. When user touch on screen, the point will run from the current position to the touched position, in speed of half the distance per second.

Android SurfaceView, run in Thread with sleep()

AndroidSurfaceViewUI.java
package com.exercise.AndroidSurfaceViewUI;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class AndroidSurfaceViewUI extends Activity {

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

private float initX, initY;
private float targetX, targetY;
private boolean drawing = true;

public class MySurfaceThread extends Thread {

private SurfaceHolder myThreadSurfaceHolder;
private MySurfaceView myThreadSurfaceView;
private boolean myThreadRun = false;

public MySurfaceThread(SurfaceHolder surfaceHolder, MySurfaceView surfaceView) {
myThreadSurfaceHolder = surfaceHolder;
myThreadSurfaceView = surfaceView;
}

public void setRunning(boolean b) {
myThreadRun = b;
}

@Override
public void run() {
// TODO Auto-generated method stub
//super.run();
while (myThreadRun) {
Canvas c = null;
try {
c = myThreadSurfaceHolder.lockCanvas(null);
synchronized (myThreadSurfaceHolder) {
myThreadSurfaceView.onDraw(c);
}

sleep(500);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
myThreadSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{

private MySurfaceThread thread;

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
//super.onDraw(canvas);
if(drawing){
canvas.drawRGB(0, 0, 0);
canvas.drawCircle(initX, initY, 3, paint);
if ((initX==targetX) && (initY==targetY)){
drawing = false;
}
else{
initX = (initX + targetX)/2;
initY = (initY + targetY)/2;
}
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
//return super.onTouchEvent(event);
int action = event.getAction();

if (action==MotionEvent.ACTION_DOWN){
targetX = event.getX();
targetY = event.getY();
drawing = true;
}

return true;
}

public MySurfaceView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}

public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}

public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}

private void init(){
getHolder().addCallback(this);
thread = new MySurfaceThread(getHolder(), this);

setFocusable(true); // make sure we get key events

paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(Color.WHITE);

initX = targetX = 0;
initY = targetY = 0;

}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
thread.setRunning(true);
thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);

MySurfaceView mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
}
}



Download the file.

No comments:

Post a Comment