Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pause and Resume AsyncTasks? (Android)

Tags:

java

android

I have an AsyncTask that acts as a countdown timer for my game. When it completes the countdown it displays the out of time end screen and it also updates the timer displayed on the screen. Everything works fine, except I need to be able to pause and resume this when the pause button in the game is pressed.

If I cancel it and try to re-execute it, it crashes with an IllegalStateException. If I cancel it and instantiate a new AsyncTask in its place the old one begins to run again and the new one runs at the same time.

Is there a way to cancel/pause the timer and restart it using AsyncTasks or is there a different way I should be going about doing this?

EDIT:

This is what I did for a solution:

mhandler = new Handler();

        mtimerTask = new Runnable(){
                public void run(){
                    mtimer -= 1;
                    if(mtimer == 0)
                    {
                        mhandler.removeCallbacks(this);
                    }
                    mhandler.postDelayed(this, 1000);
                }
        };
        mhandler.removeCallbacks(mtimerTask);
        mhandler.post(_timerTask)`

Not sure if it's the best way to go about it, but it worked for me.

like image 263
Matt Swanson Avatar asked Mar 19 '10 02:03

Matt Swanson


2 Answers

I have an AsyncTask that acts as a countdown timer for my game.

That is not a good use of AsyncTask. AsyncTasks should do work and be done, not try hanging around. For a countdown timer, use postDelayed() -- you don't even need a background thread. Or, use CountDownTimer.

If I cancel it and try to re-execute it, it crashes with an IllegalStateException.

The documentation states: "The task can be executed only once (an exception will be thrown if a second execution is attempted.)"

like image 160
CommonsWare Avatar answered Oct 20 '22 00:10

CommonsWare


Hi
Here is another dirty solution to pause an AsyncTask, which works for me.
But it is not really a clean code. Do it in your class that extends AsyncTask.

public void pause()
    {
        this.isPaused = true;
    }

    public void resume()
    {
        this.isPaused = false;
    }

    @Override
    protected Void doInBackground(Void... params)
    {
        while(!isCancelled())
        {
            while(isPaused)
                sleep(5000);

//...

private void sleep(long sleepDuration)
    {
        try
        {
            Thread.sleep(sleepDuration);
        }
        catch(InterruptedException e)
        {
            e.printStackTrace();
        }
    }
like image 41
JacksOnF1re Avatar answered Oct 20 '22 01:10

JacksOnF1re