title: How should i handle resetting SurfaceView and Thread when my game should restart?
body: <p>I'm new to both android and game development and have been trying to create a pong clone to get to grips with everything. I have a "PongView" class which extends SurfaceView and a "PongThread" which extends thread. </p>
  
  <p>I have found a way to detect if the ball or "bomb" has gotten past the paddle and reached the wall behind it. I'm not sure if my approach is the best (opinions welcome) but it seems to work as i have a little toast message displaying game over if it happens. <strong>Now i want to set it up so that, as well as displaying game over, the view restarts (or whatever the more appropriate term is) so that the bomb is in the center of the screen again and the user can play another round.</strong></p>
  
  <p><strong>Due to inexperience im not really sure how i should handle the thread and what methods to call in the view to achieve this.</strong> </p>
  
  <p>I've had several stabs at trying to figure it out but i have no idea if i'm on the right track, it'll probably be pretty clear from my code that i don't know what i'm doing. <strong>(at the moment my thread stops and my surface is just stuck displaying the last frame).</strong> Any advice will be welcome!</p>
  
  <p><em>PongView.java: (scroll down to the update method to get to the section i'm trying to figure out)</em></p>
  
  <pre><code>package biz.hireholly.pirateponggame;
  
  import android.content.Context;
  import android.graphics.BitmapFactory;
  import android.graphics.Canvas;
  import android.graphics.Color;
  import android.os.Handler;
  import android.view.MotionEvent;
  import android.view.SurfaceHolder;
  import android.view.SurfaceHolder.Callback;
  import android.view.SurfaceView;
  import android.widget.Toast;
  
  
  public class PongView extends SurfaceView implements Callback{
  
      /*GLOBALS*/
      private static final String TAG = PongView.class.getSimpleName(); 
      private PongThread pongThread;
      private Bomb bomb;
      private Paddle paddleA;
      private int viewWidth;
      private int viewHeight;
      Handler handler;
      boolean gameOver;
  
      public PongView(Context context) {
  
  
          super(context);
          // sets current class as the handler for the events happening on the surface
          getHolder().addCallback(this);
  
  
          //instantiate thread, pass the current holder and view so that the thread can access them
          pongThread = new PongThread(getHolder(), this);
  
          //make the GameView focusable so it can handle events 
          setFocusable(true);
  
          handler = new Handler();
      }
  
      //CURRENTLY WHERE IM INITIALISING SPRITES
      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int width,
              int height) {
  
          //INITIALISE viewWidth and viewHeight here
          //so that they can be passed as parameters
          viewWidth = getWidth();
          viewHeight = getHeight();
  
  
          //NEW BOMB, INITIAL BITMAP
          bomb = new Bomb(BitmapFactory.decodeResource(
                  getResources(), R.drawable.bombsprite),
                  getWidth() /2, getHeight() /2); //draws in middle
          //bombs random starting direction
          bomb.getSpeed().randomiseDirection();
  
          //NEW PADDLE, INITIAL BITMAP
          paddleA = new Paddle(BitmapFactory.decodeResource(
                          getResources(), R.drawable.paddlesprite),
                          getWidth() /2, getHeight() -(getHeight()/30) ); //middle bottom screen
      }
  
      @Override
      public void surfaceCreated(SurfaceHolder holder) {
          pongThread = new PongThread(getHolder(), this); //needed if user exits and returns
          pongThread.setRunning(true);
          //.start() == PongThread.run() except PongThread does all the work
          pongThread.start();
      }
  
  
      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
          boolean retry = true;
          while(retry){
              try{
                  //tells thread to shut down and waits for it to finish. Clean shutdown
                  pongThread.setRunning(false);
                  pongThread.join();
                  retry = false;
              } catch(InterruptedException e){
                  //try again shutting down the thread
              }
          }
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent event)
      {
          paddleA.onTouchEvents(event, viewWidth);
  
          return true;
      }
  
  
      /**
       * CHECKS FOR COLLISIONS, CALLS OBJECT UPDATE METHODS
       */
      public void update(){
  
          gameOver = false;
  
          //CHECK IF NULL as objects aren't created till surface change 
          if(bomb != null &amp;&amp; paddleA != null){
  
              bomb.handlePaddleCollision(paddleA); 
              gameOver = bomb.handleWallCollision(viewWidth, viewHeight); 
  
              //object physics updates
              bomb.update();
              //paddleA.update();
          }
  
          //WHEN handleWallColision returns true, one player scored and its game over.
          if( gameOver ){
  
  
              //handler is needed as alerts and toasts can only be made in the ui thread, 
              handler.post(new Runnable(){
                  public void run(){
                      Toast.makeText(getContext(), "GAME OVER", Toast.LENGTH_LONG).show();
                  }
              });
  
              /*THIS IS WHERE I'M TRYING TO RESTART THE GAME*/
              ///////////////////////////////////////////////////////
              //could maybe call surfaceDestroyed here instead?
              boolean retry = true;
              while(retry){
                  try{
                      //tells thread to shut down and waits for it to finish. Clean shutdown
                      pongThread.setRunning(false);
                      pongThread.join();
                      retry = false;
                  } catch(InterruptedException e){
                      //try again shutting down the thread
                  }
              }
  
              //copied from surfaceCreated
              pongThread = new PongThread(getHolder(), this); //needed if user exits and returns
              pongThread.setRunning(true);
              //.start() == PongThread.run() except PongThread does all the work
              pongThread.start();
  
              ////////////////////////////////////////////////////////
          }
      }
  
      protected void render(Canvas canvas)
      {
          canvas.drawColor(Color.GREEN);
          bomb.draw(canvas);
          paddleA.draw(canvas);
      }
  
  }
  </code></pre>
  
  <p><em>PongThread.java:</em></p>
  
  <pre><code>package biz.hireholly.pirateponggame;
  
  import android.graphics.Canvas;
  import android.util.Log;
  import android.view.SurfaceHolder;
  
  public class PongThread extends Thread {
  
      /*GLOBALS*/
      private static final String TAG = PongThread.class.getSimpleName();
      //desired frames per second
      private final static int MAX_FPS = 30;
      //maximum number of frames to be skipped if drawing took too long last cycle
      private final static int MAX_FRAME_SKIPS = 5;
      //cycle period (cycle = update,draw,if excess time sleep)
      private final static int CYCLE_PERIOD = 1000 / MAX_FPS;
      //Surface holder that can access the physical surface
      private SurfaceHolder surfaceHolder;
      //the view that actually handles inputs and draws to the surface
      private PongView pongView;
      //flag to hold game state
      private boolean running;    
  
      public void setRunning(boolean running){
              this.running = running;
      }
  
      /**Takes PongView instance and surfaceHolder as parameters
      * so that we can lock the surface when drawing.
      * @param surfaceHolder
      * @param pongView
      */
      public PongThread(SurfaceHolder surfaceHolder, PongView pongView){
          super();
          this.surfaceHolder = surfaceHolder;
          this.pongView = pongView;
      }
  
      @Override
      public void run(){
          //canvas is a surface bitmap onto which we can draw/edit its pixels
          Canvas canvas;
          Log.i(TAG, "Starting pong thread");
  
          long beginTime =0; // time when cycle began
          long timeDiff =0; // time it took for the cycle to execute
          int sleepTime =0; // milliseconds to sleep (&lt;0 if drawing behind schedule) 
          int framesSkipped =0; // number of frames skipped
  
          while (running) {
              canvas = null;
              //try locking canvas, so only we can edit pixels on surface
              try{
                  canvas = this.surfaceHolder.lockCanvas();
                  //sync so nothing else can modify while were using it
                  synchronized (surfaceHolder){ 
                      beginTime = System.currentTimeMillis();
                      framesSkipped = 0; //reset frame skips
  
                      //UPDATE game state
                      this.pongView.update();
                      //RENDER state to screen, draws the canvas on the view
                      this.pongView.render(canvas);
  
                      //calculate how long cycle took
                      timeDiff = System.currentTimeMillis() - beginTime;
                      //calculate potential sleep time
                      sleepTime = (int)(CYCLE_PERIOD - timeDiff);
  
                      //sleep for remaining cycle
                      if (sleepTime &gt;0){
                          try{
                              //saves battery
                              Thread.sleep(sleepTime);
                          } catch (InterruptedException e){}
                      }
  
                      //if there's no leftover cycle time then we're running behind
                      while (sleepTime &lt; 0 
                              &amp;&amp; framesSkipped &lt; MAX_FRAME_SKIPS){
                          //we need to catch up so we update without rendering
                          this.pongView.update();
                          sleepTime += CYCLE_PERIOD;
                          framesSkipped++;
                      }
                  }
              } finally{
                  //in case of exception, 
                  //surface is not left in an inconsistent state
                  if (canvas != null){
                      surfaceHolder.unlockCanvasAndPost(canvas);
                  }
              }//end finally
          }
      }
  }
  </code></pre>