Here's an example of the structure of a thread which stops when back is hit, which I made for my game (and works). One key difference is you're using a thread in your Activity, while in mine I call a View in my Activity and run the thread in the View. If I hit back, I return to my Activity, and can call the thread again by hitting 'start.' BECAUSE my thread behaves the way you want yours too, even if it's happening in View, I thought you may find it helpful.
Where my of my synchronization happens is with the touchscreen values, and making sure those are updated in the thread and calling function.
The thread is trashed totally unless you have a way of saving the state (if you need to).
Your thread will need to synchronize with other functions you want controlling/sharing values with the thread, like onPause, etc..
**you'll need to have some synchronized test value inside your while loop which can then change state to false, otherwise the thread will continue on its own, which is the point of threads.
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private final GameActivity gameActivity;
private GameThread _thread;
private boolean previouslyRunning = false;
private int width; //Screen width
private int height; //Screen height
private boolean newGame = true;
public GameView(Context context) {
super(context);
getHolder().addCallback(this);
this.gameActivity = (GameActivity) context;
_thread = new GameThread(getHolder(), this);
setFocusable(true);
setFocusableInTouchMode(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w;
height = h;
super.onSizeChanged(w, h, oldw, oldh);
//_thread.initialize();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (!previouslyRunning) {
_thread = new GameThread(getHolder(), this);
_thread.initialize();
}
_thread.setRunning(true);
_thread.start();
previouslyRunning = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//TODO - this was an Auto-generated method stub...
//TODO - research what this might be useful for
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//Put stuff that needs destructed here.
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// will will try again and again
//TODO: figure it out....
}
}
}
public boolean onTouchEvent(MotionEvent event) {
int numPointers = event.getPointerCount();
int ptrIdx = 0;
int touch = event.getActionMasked();
if (touch == MotionEvent.ACTION_DOWN) {
while (ptrIdx < numPointers) {
int id = event.getPointerId(ptrIdx);
float xp = event.getX(ptrIdx) / width;
if (xp > 0.6) {
_thread.shieldFront = false;
}
if (xp > 0.6 && !attacks) {
attacks = true;
_thread.attackandDefendToggle(true);
} else if (xp > 0.6 && attacks) {
attacks = false;
_thread.attackandDefendToggle(false);
} else if ((xp < 0.4 && xp > 0.2) && !movedRight) {
movedRight = true;
_thread.moveRight(true);
} else if ((xp < 0.4 && xp > 0.2) && movedRight) {
movedRight = false;
_thread.moveRight(false);
} else if (xp < 0.2 && !movedLeft) {
movedLeft = true;
_thread.moveLeft(true);
} else if (xp < 0.2 && movedLeft) {
movedLeft = false;
_thread.moveLeft(false);
}
ptrIdx++;
}
}
if (touch == MotionEvent.ACTION_UP) {
_thread.moveLeft(false);
_thread.moveRight(false);
_thread.attackandDefendToggle(false);
attacks = false;
_thread.shieldFront = true;
}
return true;
}
class GameThread extends Thread {
/****************************
* Public functions *
****************************/
public GameThread(SurfaceHolder surfaceHolder, GameView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
// put sounds here.
soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
//more sounds later
//TODO: create sounds
}
/************************************************
* update() function updates all variables, *
* such as physics, Canvas draw points, score *
* life, etc.. It is called before draw. *
************************************************/
private void update() {
// all the values I want updated with each callback
}
/************************************************
* draw() function creates images on screen, *
* but it performs no logic. *
************************************************/
private void draw(Canvas canvas) {
if (canvas == null) {
return;
}
//Draw stuff on screen
}
public void initialize() {
// Values I want the program to start with;
}
public void setRunning(boolean run) {
_run = run;
}
//Code below actually runs the thread.
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
// Update the game state
update();
// Draw image
draw(c);
}
} 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) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}