-1

Good morning! I'm trying to do a pause button for my game, but having problems with initializing the timer task again when I want to resume the game.

I get the error "java.lang.IllegalStateException: TimerTask is scheduled already", which according to my research is because the TimerTask cannot be reused so a new instance must be created of it. I tried making a method in my MainActivity that would be used for this purpose, however, that did not work. This is what I'm working with:

public class MainActivity extends AppCompatActivity{
    public FishView gameView;

    //pause variables
    Button pauseButton;
    private boolean pauseFlag = false;

    private final long animationPeriod = 600;
    Timer movementTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        screen = findViewById(R.id.gameScreen);
        gameView = new FishView(this);
        screen.addView(gameView);

        pauseButton = findViewById(R.id.pauseButton);

        movementTimer = new Timer();
        movementTimer.scheduleAtFixedRate(animationTask, 0, animationPeriod);
    }

    //this is the timer I want to reuse 
    private TimerTask animationTask = new TimerTask() {
        @Override
        public void run() {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    //set animation
                    int selectedFish = gameView.getSelectedFish();
                    if (selectedFish==1){
                        gameView.setSelectedFish(0);}
                    if (selectedFish==0){
                        gameView.setSelectedFish(1); }

                    //update screen
                    gameView.invalidate();

                }
            });
        }
    };


     public void pauseGame(View v){
        String resume = "Resume";
        String pause = "Pause";
        if (!pauseFlag){
            System.out.println("Turning timer of");
            pauseFlag = true;
            pauseButton.setText(resume);
            movementTimer.cancel();
            movementTimer=null;
        }
        else{
            System.out.println("Starting timer again");
            pauseFlag=false;
            pauseButton.setText(pause);
            try{
                movementTimer = new Timer();
                TimerTask newAnimationTask; //this did not work
                createNewAnimationTask(newAnimationTask); //this did not work
                movementTimer.scheduleAtFixedRate(animationTask, 0, animationPeriod); //here is where the error occurs
}
            catch (Exception e){
                System.out.println("ERROR: " + e);}

        }
    }

   //attempted to make method that would generate new TimerTasks
   public void createNewAnimationTask(TimerTask newAnimationTask){
        newAnimationTask = new TimerTask() {
        @Override
        public void run(){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Animation at work");
                    //here we set the animation
                    int selectedFish = gameView.getSelectedFish();
                    if (selectedFish==1){
                        gameView.setSelectedFish(0);}
                    if (selectedFish==0){
                        gameView.setSelectedFish(1); }

                    //update screen
                    gameView.invalidate();

                }
            });
        }
    };
    }



}

What I'm wondering is how do I create a new TimerTask (like the "animationTask"), whenever I press the resume button?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Android999
  • 72
  • 7

2 Answers2

1

I solved it. I removed all the TimerTask and just created everything in a function, like so:

public void createNewAnimationTask(){
        movementTimer = new Timer();
        TimerTask newAnimationTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Animation at work");
                        //here we set the animation
                        int selectedFish = gameView.getSelectedFish();
                        if (selectedFish==1){
                            gameView.setSelectedFish(0);}
                        if (selectedFish==0){
                            gameView.setSelectedFish(1); }

                        //update screen
                        gameView.invalidate();
                    }
                });
            }
        };
        movementTimer.scheduleAtFixedRate(newAnimationTask, 0, animationPeriod);
    }



Android999
  • 72
  • 7
0

Try adding the purge command also like;

movementTimer.cancel(); 
movementTimer.purge();
Erik
  • 5,039
  • 10
  • 63
  • 119
  • I have already done that as showed above and I have also tried "purge()" and it doesn't help. The problem is not with the Timer, but with the TimerTask. I need to be able to generate new TimerTasks somehow. Preferably without having to make a new class for it. – Android999 May 14 '19 at 08:47
  • Check this [Timertask or Handler](https://stackoverflow.com/questions/20330355/timertask-or-handler) – Erik May 14 '19 at 08:50
  • I posted a new working solution now. Do you have any idea how to write the duplicate code to only one? – Android999 May 14 '19 at 08:56
  • Cant you just from `onCreate` call the `pauseGame(View v)` directly, setting the Field `pauseFlag = true`, and not start the timer in `onCreate` – Erik May 14 '19 at 09:01
  • 1
    Yes probably, but I just put everything in a function now so I can call on it whenever I want to initiate a new timer. – Android999 May 14 '19 at 09:05