恢复活动时“线程已经开始”
-
01-10-2019 - |
题
这是我的情况:我正在为Android构建游戏,并且我的游戏活动由一个自定义SurfaceView组成,它具有用于游戏逻辑和渲染的线程。该架构类似于Google网站的Lunarlander演示。
当活动开始时,它会创建SurfaceView并调用此方法:
@Override
public void surfaceCreated(SurfaceHolder holder)
{
renderThread.start();
}
当我按“主页”按钮退出游戏时,称为onpause()方法,该方法调用surfaceDestroyed()。在表面上,我通过打电话来停止游戏线程:
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
synchronized(holder)
{
renderThread.stop();
}
}
该应用程序恰好是背景。然后,当我按照图标重新启动应用程序时,我在日志中收到“线程已经启动”消息,以及屏幕上的“力量关闭”弹出窗口。当活动在渲染线程上调用start()时,该消息会输入“表面处理”方法时。
现在,我已经研究了几个小时,无法弄清楚为什么这是。我相信当我关闭应用程序时,我的线程被停止了,所以我不明白为什么它已经开始。
解决方案
这些方法不做您认为他们所做的事情。来自 API文档:
启动多次线程从来没有合法。
和:
public final void stop()
- 弃用。此方法本质上是不安全的。
如果要暂停线程,则必须使用 Object.wait()
和 Objecft.notifyAll()
从线程内。
其他提示
我认为,如果您打算启动和停止线程,则不应将代码打包到线程的子类中(示例这样做是因为它使代码较短)。改用可运行的。这样,您可以在需要时停止并丢弃旧线程,并创建一个新线程对象,以在需要重新启动时执行可运行的对象。
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) {
}
}
}
同样,依靠例外是不良形式。当您自己的代码出乎意料的行为时,应该将其用作最后的手段。
一个不好的解决方案,但它有效。
public void surfaceCreated(SurfaceHolder holder) {
try{
_thread.setRunning(true);
_thread.start();
}catch(Exception ex){
_thread = new TutorialThread(getHolder(), this);
_thread.start();
}
}
纠正受到热烈欢迎。
不隶属于 StackOverflow