1

发生 onPause 时我的线程没有停止,导致 onResume 出现“线程已启动”logcat 错误,因为我不能运行两个线程实例。此时如何终止线程?我相信我需要做类似的事情:

gameLoopThread.setRunning(false);

但是我不能将它添加到我的 balloonBasic onPause 中,我认为上下文是错误的。所以请帮忙,代码如下所示。(代码示例真的很有帮助,谢谢)

我的活动:

public class balloonBasic extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(new GameViewBasic(this));
}

public void onResume() {
    super.onResume();
    SoundManager.getInstance();
    SoundManager.initSounds(this);
    SoundManager.loadSounds();
    }

public void onPause() {
    super.onPause();
    //what do I put here?
}
}

我的表面观点:

public class GameViewBasic extends SurfaceView {

...abbreviated declarations...
private static SurfaceHolder holder;
private static GameLoopThreadBasic gameLoopThread;

   public GameViewBasic(Context context) {
         super(context);
         gameLoopThread = new GameLoopThreadBasic(this);
         holder = getHolder();
         holder.addCallback(new Callback() {



                public void surfaceDestroyed(SurfaceHolder holder) 
                {
                    gameLoopThread.setRunning(false);
                }


                public void surfaceCreated(SurfaceHolder holder) {

                       createSprites();
                       mapspritegraphics();

                       gameLoopThread.setRunning(true);
                       gameLoopThread.start();

                }

                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
                {
                }
         });
   }
...abbreviated for brevity....

我的线程: public class GameLoopThreadBasic extends Thread { private GameViewBasic view; 私有易失性布尔运行=假;

   public GameLoopThreadBasic(GameViewBasic gameViewBasic) {
         this.view = gameViewBasic;
   }
   public void setRunning(boolean run) {
         running = run;
   }

   @Override
   public void run() {
         long ticksPS = 25; // =(1000/fps) ie 25ticksPS = 40fps
         long startTime;
         long sleepTime;

         while (running) {
                Canvas c = null;
                startTime = System.currentTimeMillis();
                try {
                       c = view.getHolder().lockCanvas();
                       synchronized (view.getHolder()) {
                              view.onDraw(c);
                       } 

                } catch (Exception f) {} //
                finally {
                       if (c != null) {
                              view.getHolder().unlockCanvasAndPost(c);
                       }
                } 
                sleepTime = (ticksPS - (System.currentTimeMillis() - startTime));
                try {
                       if (sleepTime > 0)
                              sleep(sleepTime);
                       else
                              sleep(10);
                } catch (Exception e) {}
         }
   }
}
4

1 回答 1

4

前段时间我在做一个游戏,我在早期阶段使用 LunarLander 作为灵感……但事实证明,LunarLander 示例代码实际上有这个错误(试图启动一个已经在运行的线程)!下面是该问题的解决方案,在扩展 SurfaceView 的类中。我在某处网上找到了解决方案,但我不记得在哪里,因为那是很久以前的事了。

public void surfaceCreated(SurfaceHolder holder)
{
    if (mMyThreadName.getState() == Thread.State.TERMINATED)
    {
        mMyThreadName = new MyThreadName(xxx);
    }

    mSurfaceIsReady = true;
    mMyThreadName.start();
}

请注意,我还调用了 mMyThreadName = new MyThreadName(xxx); 在扩展 SurfaceView 的同一类的构造函数中。我认为我的 surfaceDestroyed 回调与 LunarLander 一样,即。mSurfaceIsReady 在那里被设置为 false 等等。

编辑

LunarLander 中的 Android IllegalThreadStateException

看起来可能有比我上面发布的代码更好的解决方案。相反,可以始终只在surfaceCreated 中实例化线程,而不检查它是否已终止,并且不要在其他任何地方实例化它。我还没有尝试过第二种方法!

我可能误解了你的问题,如果我很抱歉。

于 2013-05-05T09:03:59.887 回答