这是我的情况: 我正在构建一个Android游戏,我的游戏活动由一个自定义的surfaceView组成,它有一个游戏逻辑和渲染的线程。该架构类似于Google网站上的LunarLander演示。
当活动开始时,它会创建surfaceView并调用此方法:
@Override
public void surfaceCreated(SurfaceHolder holder)
{
renderThread.start();
}
当我按下主页按钮退出游戏时,会调用onPause()方法,该方法调用surfaceDestroyed()。在surfaceDestroyed中,我通过调用停止游戏线程:
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
synchronized(holder)
{
renderThread.stop();
}
}
该应用程序适用于背景。然后,当我通过按下图标重新启动应用程序时,我在日志中收到“Thread already started”消息以及屏幕上的“强制关闭”弹出窗口。当活动在渲染线程上调用start()时进入“surfaceCreated”方法时会发生此消息。
现在我已经研究了好几个小时,无法弄清楚为什么会这样。我相信当我关闭应用程序时我的线程已停止,所以我不明白为什么它说它已经开始了。
答案 0 :(得分:8)
这些方法不符合您的想法。来自API doc:
启动一个线程永远不合法 不止一次。
和
public final void stop()
- 已弃用。这种方法本质上是不安全的。
如果您想暂停一个主题,则必须在主题中使用Object.wait()
和Objecft.notifyAll()
。
答案 1 :(得分:5)
在我看来,如果你想要经常启动和停止线程,你不应该将你的代码打包到Thread的子类中(这些例子是因为它使代码更短)。请改用Runnable。这样你可以在需要时停止并丢弃旧的Thread,并在需要再次启动时创建一个新的Thread对象来执行Runnable。
private TutorialRunnable tutorialRunnable;
...
// Synchronization and error checking omitted for brevity.
public void surfaceCreated(SurfaceHolder holder) {
thread = new Thread(tutorialRunnable);
thread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
tutorialRunnable.setRunning(false);
while (thread != null) {
try {
thread.join();
thread = null;
} catch (InterruptedException e) {
}
}
}
此外,依赖异常是不好的形式。当你自己的代码出乎意料地行为时,这应该被用作最后的手段。
答案 2 :(得分:0)
一个糟糕的解决方案,但它有效..
public void surfaceCreated(SurfaceHolder holder) {
try{
_thread.setRunning(true);
_thread.start();
}catch(Exception ex){
_thread = new TutorialThread(getHolder(), this);
_thread.start();
}
}
我们热烈欢迎更正。