1

I am using an Asynctask as the loop controller for a game and noticed that the thread created kept on running after the activity was finished.

I realised that was the correct behaviour of a separate thread and then I tried hunting down answers on how to end the thread when the app enters onPause.

I found lots of similar questions but no direct answers but eventually came up with a method so I'm going to answer my own question here to hopefully help others in future. (And to receive improvements to my answer as well)

SimpleSi
  • 753
  • 1
  • 10
  • 22

2 Answers2

2

Firstly, AsyncTask have a fully valid cancel() method. Secondly, do not use an AsyncTask for a proper game loop. AsyncTask isn't for long-running operations.

Therefore, skip AsyncTask for your game loop and learn how to properly manage pausing / resuming in an ordinary Thread by reading another answer from me here on SO.

Community
  • 1
  • 1
Wroclai
  • 26,835
  • 7
  • 76
  • 67
  • AsyncTask does have a fully valid cancel() method but I can't find clear documentation on how to use it :) As a part-time enthusiast unless your going to show me that how really bad things will happen to my app if I use Asynctask as a simple loop controller I'm going to use it as an easy way of making a game loop thread :) I think I'm doing quite well in following "the rules" by even having a separate thread :) – SimpleSi Apr 23 '11 at 22:09
  • The problem when you're invoking a `cancel()` on your `AsyncTask` is that once you're resuming your game you have to start over by creating a new `AsyncTask`. This is bad practice, especially in game development. Although, if you want to have it like that, here is a good answer on how you can cancel an `AsyncTask`. http://stackoverflow.com/questions/5513855/android-asyntask-with-progress-dialog-cancel/5513904#5513904 – Wroclai Apr 23 '11 at 22:17
  • Maybe I have asked the wrong question :( In my code I run task.cancel(true) in OnPause but the AsyncTask doesn't end and I therefore get another thread running the next time I launch the app :(. So I have had to include a check of this.isCancelled inside my Asynctask. – SimpleSi Apr 23 '11 at 22:26
  • If you read the documentation from the `cancel()` method you'll find this: *Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.* – Wroclai Apr 23 '11 at 22:28
  • [quote]then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task[/quote]And can you find any example of that usage on the'net? - I can't :) – SimpleSi Apr 23 '11 at 22:36
  • Why do you need an example? Pass true as a parameter if you wanna cancel, otherwise pass false. – Wroclai Apr 23 '11 at 22:43
  • :) The main point of my question was to let me post my own answer so that others searching for the answer to the question of Asynctasks not cancelling would have an example solution :) At the moment I have to wait 8 hours before I'm allowed to answer my own question so I can't post a solution. But if you can ... :) – SimpleSi Apr 23 '11 at 22:51
0
public class CamOverlayTest extends Activity {
//...
public static BackgroundLoop BackgroundLoopTask;
//...

@Override
protected void onResume() {
    //...

    BackgroundLoopTask = new BackgroundLoop();
    BackgroundLoopTask.execute();


}

@Override
protected void onPause() {
    //...
    BackgroundLoopTask.cancel(true);
}

private class BackgroundLoop extends AsyncTask<Void,Integer,Boolean> {

    @Override
    protected Boolean doInBackground(Void... arg0) {
        int count =0;

        while (!this.isCancelled()) {
        // Basically, this is where the loop checks if the Aysnctask has been asked to be
        // cancelled - if so - it exits.
            try {
                Thread.sleep(1000);
                updatePhysics(count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count +=1;
            Log.i("SW","Count: "+count);
            publishProgress();

        }
        return true;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // swDrawOnTop is my view 
        swDrawOnTop.invalidate();
    }
//...

}

SimpleSi
  • 753
  • 1
  • 10
  • 22