I am creating a demo game in Android for learning purposes. In the game, when a collision is detected between two objects - I want to show a "game over" dialog. Inside the dialog box there is a play again button. When pressed, the thread should be started again.
I am getting the following error java.lang.IllegalThreadStateException: Thread already started .
Here is my code:
public class GamePanel extends SurfaceView implements Runnable {
    private Thread thread = null;
    private Ball ball;
    private SurfaceHolder surfaceHolder;
    private Paint paint;
    private Canvas canvas;
    volatile boolean playing = true;
    private int hurdleCount = 3;
    private Hurdles[] hurdles;
    private int screenX, screenY;
    private Rect ball_detectCollision;
    public GamePanel(Context context, final int screenX, final int screenY) {
        super(context);
        ball = new Ball(context, screenX, screenY);
        surfaceHolder = getHolder();
        this.screenX = screenX;
        this.screenY = screenY;
        paint = new Paint();
        canvas = new Canvas();
        hurdles = new Hurdles[hurdleCount];
        for (int i = 0; i < hurdleCount; i++) {
            hurdles[i] = new Hurdles(context, screenX, screenY);
        }
        ball_detectCollision = new Rect(ball.getBall_x(), ball.getBall_y(), ball.getBitmap().getWidth(), ball.getBitmap().getHeight());
        surfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                System.out.println("Surface Created");
                setUpdated_x(ball.getBall_x());
            }
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                System.out.println("Surface Changed");
                thread = new Thread(GamePanel.this);
                thread.start();
            }
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                System.out.println("Surface Destroyed");
            }
        });
    }
    public int getUpdated_x() {
        return updated_x;
    }
    public void setUpdated_x(int updated_x) {
        this.updated_x = updated_x;
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        setUpdated_x((int) event.getX());
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_DOWN:
                initial_X = getUpdated_x();
                break;
            case MotionEvent.ACTION_MOVE:
                if (getUpdated_x() < screenX - ball.getBitmap().getWidth() || getUpdated_x() > screenX - ball.getBitmap().getWidth()) {
                    draw(getUpdated_x());
                }
                break;
        }
        return true;
    }
    private void draw(int updatedValue) {
        canvas = surfaceHolder.lockCanvas();
        canvas.drawColor(Color.RED);
        canvas.drawBitmap(ball.getBitmap(), updatedValue, ball.getBall_y(), paint);
        ball.setBall_x(updatedValue);
        ball_detectCollision.left = ball.getBall_x();
        ball_detectCollision.top = screenY - ball.getBitmap().getHeight() - 260;
        ball_detectCollision.right = ball.getBall_x() + ball.getBitmap().getWidth();
        ball_detectCollision.bottom = screenY - ball.getBitmap().getHeight() - 260 + ball.getBitmap().getHeight();
        for (int i = 0; i < hurdleCount; i++) {
            canvas.drawBitmap(hurdles[i].getBitmap(), hurdles[i].getX(), hurdles[i].getY(), paint);
        }
        surfaceHolder.unlockCanvasAndPost(canvas);
    }
    @Override
    public void run() {
        while (playing) {
            update();
            draw(getUpdated_x());
            control();
        }
    }
    private void update() {
        for (int i = 0; i < hurdleCount; i++) {
            hurdles[i].update();
            if (Rect.intersects(getBall_detectCollision(), hurdles[i].getDetectCollision())) {
                System.out.println("Collision Detected");
                playing = false;
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        showGameOverMessage();
                    }
                });
            }
        }
    }
    public void pause() {
        playing = false;
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private void showGameOverMessage() {
        Toast.makeText(getContext(), "Game Over", Toast.LENGTH_SHORT).show();
        Dialog showDialog = new Dialog(getContext());
        showDialog.setContentView(R.layout.dialog_game_over);
        Button playAgainButton = (Button) showDialog.findViewById(R.id.playAgainButton);
        playAgainButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                playing = true;
                thread.start();
            }
        });
        showDialog.show();
    }
}