简体   繁体   中英

Android thread activity lifecycle

I'm making a game for android and i'm running into some problems with my thread when I exit my game and restart it again. I'm trying to interrupt the thread in the onPause function in MainActivity and resuming the thread in the start function in gamepanel with notify. It sometime works but it's not really pausing the game.

What is the proper way to implement the activity lifecycle while pausing a thread? Especially a game thread where game update functions shouldn't be called while the user is away.

public class MainActivity extends Activity {

private GamePanel gamepanel;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    //removes title
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    //full screen
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    gamepanel = new GamePanel(this);

    setContentView(gamepanel);

    SoundHandler.setContext(this);

}

@Override
protected void onPause() {
    super.onPause();
    gamepanel.getThread().interrupt();

}

@Override
protected void onStop() {
    super.onStop();
}


@Override
protected void onRestart() {
    super.onRestart();
}

@Override
protected void onResume() {
    super.onResume();
}


@Override
protected void onDestroy() {
    super.onDestroy();
    boolean retry = true;
    while (retry) {
        try {
            gamepanel.getThread().setRunning(false);
            gamepanel.getThread().join();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        retry = false;
    }
}
}

Gamepanel that extends surfaceView:

@Override
public void surfaceDestroyed (SurfaceHolder holder){}

/**create surface.
 *
 * @param holder
 */
@Override 
public void surfaceCreated (SurfaceHolder holder){
    //we can safely start the game loop
    System.out.println("CREATING SURFACE");
    loadingscreen = false;
    start();
}

public void start() {
    if(!mGameIsRunning) {
        thread.start();
        thread.setRunning(true);
        mGameIsRunning = true;
    } else {
        thread.onResume();
    }
}

Thread class

public class MainThread extends Thread {
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
public boolean running = false;
public static Canvas canvas;
private long startTime;
private long fps = 1/30;

public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) {
    super();
    this.surfaceHolder = surfaceHolder;
    this.gamePanel = gamePanel;
    startTime = System.nanoTime();
}

@Override
public void run()
{
    while(running) {
        if((System.nanoTime() - startTime) / 1000000000> fps) {
            canvas = null;
            //try locking the canvas for pixel editing
            try {
                canvas = surfaceHolder.lockCanvas();
                synchronized (surfaceHolder) {

                    this.gamePanel.update();
                    this.gamePanel.draw(canvas);
                    this.gamePanel.checkSpeed();

                }
            } catch (Exception e) {
            } finally {
                if (canvas != null) {
                    try {
                        surfaceHolder.unlockCanvasAndPost(canvas);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }

    gamePanel.surfaceDestroyed(surfaceHolder);
}

public void onResume(){
    synchronized(this){
        this.notify();
    }
}

public void setRunning(boolean b)
{
    running=b;
}
public boolean getRunning(){
    return running;
}
}

There is no memory barrier around boolean running you can synchronize or use private volatile boolean running; . Then you need to call setRunning(false) somewhere to stop it, which you do not seem to do. These reasons are probably why your thread isn't quitting.

But I don't believe it makes any sense to render the game in a separate thread anyway. If you can't update & render super fast anyway, (eg 1/60th second or better) then moving it to a thread isn't going to help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM