9

这是我的情况:我正在为 android 构建一个游戏,我的游戏活动由一个自定义的 surfaceView 组成,它有一个用于游戏逻辑和渲染的线程。该架构类似于 Google 网站上的 LunarLander 演示。

当活动启动时,它会创建表面视图并调用此方法:

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {   
        renderThread.start();
    }

当我按下home键退出游戏时,调用了onPause()方法,该方法调用了surfaceDestroyed()。在 surfaceDestroyed 我通过调用停止游戏线程:

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        synchronized(holder)
        {
            renderThread.stop();
        }
    }       

该应用程序进入后台正常。然后,当我通过按图标重新启动应用程序时,我会在日志中收到“线程已启动”消息以及屏幕上的“强制关闭”弹出窗口。当活动在渲染线程上调用 start() 时进入“surfaceCreated”方法时,会发生此消息。

现在我已经研究了几个小时,无法弄清楚为什么会这样。我相信当我关闭应用程序时我的线程已停止,所以我不明白为什么它说它已经开始了。

4

3 回答 3

8

这些方法不会做你认为他们做的事情。从API 文档

多次启动一个线程是不合法的。

和:

public final void stop()- 已弃用。这种方法本质上是不安全的。

如果你想暂停一个线程,你必须在线程内使用Object.wait()and Objecft.notifyAll()

于 2010-06-30T10:22:20.387 回答
5

在我看来,如果您打算经常启动和停止 Thread,则不应将代码打包到 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) {
        }
    }
}

此外,依赖异常是不好的形式。当您自己的代码出现意外行为时,这应该作为最后的手段。

于 2011-11-15T10:55:49.040 回答
0

一个糟糕的解决方案,但它有效..

 public void surfaceCreated(SurfaceHolder holder) {
        try{
        _thread.setRunning(true);
        _thread.start();
        }catch(Exception ex){
            _thread = new TutorialThread(getHolder(), this);
            _thread.start();
        }

    }

欢迎指正。

于 2010-11-29T07:16:36.710 回答