java 恢复活动时“线程已启动”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3148186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:34:36  来源:igfitidea点击:

"Thread already started" when resuming the activity

javaandroidmultithreadingandroid-lifecycle

提问by NioX5199

Here is my situation: I am building a game for android and my game's activity is composed of a custom surfaceView which has a thread for the game logic and rendering. The architecture is similar to the LunarLander demo from Google's website.

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

When the activity starts it creates the surfaceView and calls this method:

当活动开始时,它会创建surfaceView并调用这个方法:

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

When I press the home button to exit the game, the onPause() method is called, which calls surfaceDestroyed(). In surfaceDestroyed I stop the game Thread by calling:

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

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

The app goes to background fine. Then, when I relaunch the app by pressing the icon, I get a "Thread already started" message in the log along with a "force close" popup on the screen. This message happens when the activity enters the "surfaceCreated" method when it calls start() on the render thread.

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

Now I've looked into it for hours and can't figure out why this is. I believe my thread is stopped when I close the app so I don't understand why it says it has already started.

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

采纳答案by Michael Borgwardt

Those methods don't do what you think they do. From the API doc:

这些方法不会做您认为它们会做的事情。来自API 文档

It is never legal to start a thread more than once.

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

And:

和:

public final void stop()- Deprecated. This method is inherently unsafe.

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

If you want to pause a thread, you have to use Object.wait()and Objecft.notifyAll()from within the thread.

如果要暂停线程,则必须在线程内使用Object.wait()Objecft.notifyAll()

回答by Torben

In my opinion you should not pack your code into a subclass of Thread if you intend to be starting and stopping the Thread often (the examples do it because it makes the code shorter). Use a Runnable instead. That way you can stop and discard the old Thread when you want and create a new Thread object to execute the Runnable when you need to start it again.

在我看来,如果您打算经常启动和停止 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) {
        }
    }
}

Also, relying on exceptions is bad form. That should be used as a last resort when your own code behaves unexpectedly.

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

回答by AZ_

A bad solution but it works..

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

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

    }

corrections are warmly welcomed.

热烈欢迎更正。