【发布时间】:2010-10-15 13:13:21
【问题描述】:
只是来完善我的应用程序并在用户离开后使其恢复。当应用程序恢复时,我得到一个 IllegalThreadStateException,这很烦人。这个问题出现在谷歌给出的Lunar Lander 的例子中。有没有人在使用surfaceView时找到了恢复工作的方法?
【问题讨论】:
标签: java android surfaceview illegalstateexception
只是来完善我的应用程序并在用户离开后使其恢复。当应用程序恢复时,我得到一个 IllegalThreadStateException,这很烦人。这个问题出现在谷歌给出的Lunar Lander 的例子中。有没有人在使用surfaceView时找到了恢复工作的方法?
【问题讨论】:
标签: java android surfaceview illegalstateexception
我相信这是由于 Surface 和 Activity 的处理方式不同造成的。当您离开 LunarLander 应用程序时,表面被销毁(调用 surfaceDestroyed),但 Activity 仅暂停(调用 onPause)。当 Activity 恢复时,表面被创建(调用 surfaceCreated)并尝试再次启动绘图线程。
这意味着创建线程发生在 Activity 的生命周期中,而销毁线程发生在 SurfaceView 的生命周期中,它们并不总是对应,因此会出现 IllegalThreadStateException。解决方案是将线程绑定到一个生命周期或另一个生命周期,而不是两者。
我认为this thread 提出了一个可能的解决方案,虽然我不知道它是否有效。
【讨论】:
在我自己的测试中,我在surfaceCreated()方法中创建了绘图线程,这样就彻底解决了这个问题。这是我的方法实现:
@Override
public void surfaceCreated(SurfaceHolder arg0) {
_thread = new DrawThread(getHolder());
_thread.setRunning(true);
_thread.start();
}
【讨论】:
所以在代码中,当surfaceDestroyed()被调用时,它会将mRun设置为false并调用thread.join()。这会导致线程完成并终止。当应用再次启动并调用surfaceCreated() 时,它会调用thread.start()。这是无效的,因为线程死后无法启动。
两个修复选项:
a) 在surfaceCreated() 中启动一个新线程 - 如上所述。
b) 或者在surfaceDestroyed() 中添加对Activity.isFinishing() 的检查,以仅在为真时结束线程。为此,我将线程中的while(mRun) 用另一个while 循环包围起来,如果isFinishing() 返回true,该循环才设置为false。
【讨论】: