恢复活动时“线程已经开始”

时间:2010-06-30 10:05:33

标签: java android multithreading android-lifecycle

这是我的情况: 我正在构建一个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”方法时会发生此消息。

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

3 个答案:

答案 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();
        }

    }
我们热烈欢迎更正。