Java 在Android中,在SurfaceView中创建的线程何时被销毁?

Java 在Android中,在SurfaceView中创建的线程何时被销毁?,java,android,multithreading,surfaceview,Java,Android,Multithreading,Surfaceview,我正在分析与相关的代码,我遇到了一些与我希望得到帮助的线程相关的混乱逻辑。如果需要,我将分析完整的源代码 我正在寻找帮助的特定代码如下所示。请注意,我省略了与问题无关的代码 public class GameView extends SurfaceView implements Runnable { private Thread gameThread; public GameView(Context context, int gameWidth, int gameHeight) {

我正在分析与相关的代码,我遇到了一些与我希望得到帮助的线程相关的混乱逻辑。如果需要,我将分析完整的源代码

我正在寻找帮助的特定代码如下所示。请注意,我省略了与问题无关的代码

public class GameView extends SurfaceView implements Runnable {
  private Thread gameThread;
  public GameView(Context context, int gameWidth, int gameHeight) {
    SurfaceHolder holder = getHolder();
    holder.addCallback(new SurfaceHolder.Callback() {
      @Override
      public void surfaceCreated(SurfaceHolder holder) {
        initGame();
      }
      @Override
      public void surfaceChanged(omitted) {omitted}
      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
        pauseGame();
      }
    });
    private void initGame() {
      gameThread = new Thread(this, "Game Thread");
      gameThread.start();
    }
    private void pauseGame() {
      while (gameThread.isAlive()) {
        try {
          gameThread.join(); 
          break;
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
}
按照我阅读此代码的方式,发生了以下相关逻辑:

  • 当应用程序首次启动并显示
    GameView
    时,将创建一个新的线程对象,并将其与
    gameThread
    变量关联
  • gameThread
    被命名,然后
    start()
    ed
  • 如果应用程序失去焦点/暂停,并且
    gameThread
    正在运行,则通过
    join()
    方法暂停
    gameThread
    。*注意,我对这个逻辑有点模糊*
  • 如果应用程序重新获得焦点/重新启动,将创建一个新线程,并将其分配给我们的
    gameshread
    变量
  • 阅读此逻辑后,我的最初反应是,“为什么我们要创建一个新线程并将其分配给
    gameThread
    ?之前创建的线程不应该仍然存在吗?”我进行了一些调试/记录,发现在游戏暂停和重新启动之间的某个时间点,
    gameThread
    线程被“销毁”,因为在创建和分配新线程之前,如果我在
    initGame()
    期间尝试对
    gameThread
    调用
    .getName()
    ,我会得到一个空指针异常。如果现有的
    gameThread
    在暂停和恢复之间被销毁,那么这不会消除与该线程相关的任何游戏状态吗


    有人能告诉我当应用程序失去焦点时线程会发生什么情况,然后重新获得它(或者给我指一个可以这样做的资源)?

    通常最好在
    onPause()
    中暂停或停止线程,这样当应用程序停止或处于其他活动时,线程就不会继续运行。本例依靠
    surfaceDestroyed()
    暂停游戏,这是不够的,因为如果用户点击电源按钮以清空显示,则表面可能不会被破坏。(注意,我没有超出您发布的内容,因此我不知道原始代码是否在
    onPause()
    中执行其他操作——如果它暂停线程活动,那么就可以了。)

    中详细介绍了SurfaceView与活动生命周期之间的交互。假设您对该文档有一定的了解

    您包含的
    pauseGame()
    方法正在调用
    Thread.join()
    ,它将等待目标线程退出。(它可能会在出现异常时提前退出,这可能是它被包装在“while”循环中的原因。)因此当
    pauseGame()
    返回时,可以保证另一个线程不再运行。您没有包含的其他一些代码必须要求线程停止