Restarting/Pausing Thread in onResume/onPause
Asked Answered
Q

4

7

I'm have a game that's uses SurfaceView implementation to display the objects. I have a thread which draws the SurfaceView time-to-time to the screen. The game is running completely. Unfortunately, it needed to have a pause function whenever the game is interrupted. Well, I know that I need to manipulate onResume and onPause.

But I can't get it right. The error points me back to surfaceCreated where I start the thread telling me that the thread has started already. I tried using the resume and suspend on the onResume and onPause respectively but nothing changed.

How can I achieve this? I have already done how the objects location would be save using File-I/O handling.

Thanks in advance.

Quemoy answered 15/8, 2011 at 17:40 Comment(1)
possible duplicate of How to pause/resume thread in Android?Portuguese
L
1

Without knowing the ins and outs of your code.

To "Pause" a thread you can implement functionality like so:

while(! this.isInterrupted())
    if(!paused)
    {
        ... Do something ...
    } else { try { Thread.sleep(100) } catch (InteruptedException ie) {} }

This is depending if Do something is invalidating your surface view or otherwise controlling progression in your app. An accessor to paused should allow you to pause and resume your thread without getting caught up in any other bit of architecture.

Lombroso answered 25/8, 2011 at 11:41 Comment(0)
L
3

This is what I did:

    @Override
    public void surfaceCreated(SurfaceHolder arg0) {
           if (thread.getState() == Thread.State.TERMINATED){
              CreateThread(getHolder(),getContext());
           }
           thread.setRunning(true);
           thread.start();
    }
  • In CreateThread you should have the thread = new MyThread(...);
  • the setRunning (boolean mRun) use a boolean to start/stop the run function (I think I was inspired by the LunarLander);

If you want to use properly the onPause/onResume don't put the variables used by your thread inside the thread (as done in LunarLander). I suggest you to do like that:

// Variables declarations

public MyGameThread CreateThread(...){
thread = new MyGameThread(holder, context, new Handler() {
// and so on....
});
}

When you pass through the onPause/onResume, your thread will be destroyed and reneweled but if you put your variables outside it, you can continue to use them after.

If you have something important to preserve, use one of this options:

  • SharedPreferences: an xml will be created and saved locally with variables that persist even after the end of the app;
  • a SQL db if you would manage more than 5-10 variables because in this case the use of the former option would be difficult.
Living answered 16/8, 2011 at 8:30 Comment(2)
Can you expand this further? I can't get in through the it. Sorry for the late response.Quemoy
Well, start studying this blog: wonton-games.blogspot.com/2010/06/… I got a lot about the "lunarlander problem" there. After that, come back with a detailed question ;)Living
A
2

Actually it's not recommended to stop a thread by yourself, the stop() method is deprecated. The simplest solution is to use a flag in your while loop inside the thread's run() method. When you need to "stop" the thread, you just drop the flag to false and the thread won't do anything anymore, despite it will keep running. Android will stop your thread when it's needed. Hope this helps.

Aspect answered 15/8, 2011 at 18:19 Comment(6)
Ok then, how then would I restart the thread running when I have set the running flag to false from onPause.Quemoy
@Cyril Horad, Your application will just start another thread with the same taskAspect
Starting another thread? But isn't that going to start the task from the beginning?Quemoy
@Cyril Horad, You should save all the info you need to resume the work, of course the task will be started from scratch, it's up to you to resume the work.Aspect
I see. But isn't going to waste time resuming the work from a bundle/file?Quemoy
@Cyril Horad, Even if it does, you have no other option. The system won't store any information when your application is paused, so you have to do it yourself.Aspect
A
1

I'm unsure if you've got one or two threads in this question, I'm assuming 2. You need to do three things when you call onPause:

1 - Save the state of the application (all game variables, states, etc)
2 - Kill the surfaceView by calling suspend.
3 - Kill the other thread (we'll call it Thread B).

Killing of Thread B is your problem I think. You want to interrupt the thread and tell it to quit, or else when you call onPause your thread will still be doing its thing. Then, when you go back into the game, the thread will try to be created again which causes the problem. There are 2 ways to kill a thread properly:

  • In the while() loop of your thread, have a boolean 'run' which while(run) will execute the code. When you change run to false, the thread exits.
  • If your thread sleeps (I assume it might do since its a game and will be running w.r.t time), catch the InterruptedException and then quit there. When you want to kill the thread, you throw the exception to the thread.

The first one is by far the easiest.

Albina answered 25/8, 2011 at 0:55 Comment(0)
L
1

Without knowing the ins and outs of your code.

To "Pause" a thread you can implement functionality like so:

while(! this.isInterrupted())
    if(!paused)
    {
        ... Do something ...
    } else { try { Thread.sleep(100) } catch (InteruptedException ie) {} }

This is depending if Do something is invalidating your surface view or otherwise controlling progression in your app. An accessor to paused should allow you to pause and resume your thread without getting caught up in any other bit of architecture.

Lombroso answered 25/8, 2011 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.