首页 文章

Android线程活动生命周期

提问于
浏览
1

我正在为Android制作一款游戏,当我退出游戏并重新启动时,我的线程遇到了一些问题 . 我正在尝试中断MainActivity中onPause函数中的线程,并使用notify在gamepanel中的start函数中恢复线程 . 它有时可行,但它并没有真正暂停游戏 .

What is the proper way to implement the activity lifecycle while pausing a thread? 特别是一个游戏线程,在用户离开时不应该调用游戏更新功能 .

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;
    }
}
}

扩展surfaceView的Gamepanel:

@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();
    }
}

线程类

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;
}
}

1 回答

  • 0

    boolean running 周围没有记忆障碍你可以 synchronize 或使用 private volatile boolean running; . 然后你需要在某个地方调用 setRunning(false) 来阻止它,你似乎没有 . 这些原因可能就是你的线程没有放弃的原因 .

    但我认为无论如何将游戏渲染到一个单独的线程中都没有任何意义 . 如果无论如何都无法更新和渲染超快(例如1/60秒或更好),那么将其移动到线程将无济于事 .

相关问题