在Android中结束线程-严重的问题

在Android中结束线程-严重的问题,android,multithreading,surfaceview,forceclose,Android,Multithreading,Surfaceview,Forceclose,对于何时/如何在我的Surfaceview应用程序中结束线程,我仍然非常困惑,希望有人能解释一下 目前,我正在使用以下代码: Log.v("Destroyed","Surface Destroyed"); preThread.setRunning(false); boolean retry = true; while (retry) { try { preThread.join(); retry = false; } catc

对于何时/如何在我的Surfaceview应用程序中结束线程,我仍然非常困惑,希望有人能解释一下

目前,我正在使用以下代码:

Log.v("Destroyed","Surface Destroyed");

preThread.setRunning(false);  
boolean retry = true;        
while (retry) {
    try {
        preThread.join();
        retry = false;
    } catch (InterruptedException e) {
    }
}
上面的代码位于我的surfaceDestroyed方法中-首先,这是正确的吗

在我的surfaceCreated方法中,我有以下代码,应该检查线程是否仍然存在或已停止,如果已停止,然后重新启动它:

if (runthread==false){

if (preThread.getState()==Thread.State.TERMINATED){
    preThread = new MainThread(thisholder, thiscontext, thishandler);}
else {}
    preThread.setRunning(true);
    preThread.start();
    }
这看起来很奇怪。以下是我得到的:

*)当我第一次安装游戏并运行它时,通过我的日志记录,它表示线程已经存在,如果我然后按back键,surfaceDestroyed将运行,但当我返回到活动时,它再次表示线程已经存在

*)如果我按home键,则会运行SurfacedStroyed,当我返回到该活动时,它会显示该线程先前已被破坏,并启动一个新线程

*)如果我使用DDMS终止活动,surfaceDestroyed不会运行,当我返回活动时,它会说线程已经存在

如果我想的很清楚,那么第三种情况是唯一有意义的

我显然做错了什么。主要问题是:

如果我在游戏中按home键,然后在Eclipse中通过DDMS结束应用程序,则重新启动应用程序并快速连续按back键两次(一次,返回上一个活动,然后再次返回初始屏幕)-应用程序强制关闭,我在logcat中得到“致命异常:线程12”。我必须假设这是因为我的线程永远不会结束,并且正在尝试重新启动?我不确定

我一直在试图弄明白这似乎是一个年龄,所以我真的希望有人能解释我做错了什么

非常感谢

编辑。Logcat输出

我的Run()方法:


线程是很难管理的,但是经过一些尝试之后,我想我已经想出了一个在大多数情况下都能正常工作的方案。 断线

 if(m_hThread != null)
        {
            try 
            {
                m_bThread = false; // m_bThread is the while condition of the thread
                m_hThread.interrupt(); // incase the thread is in sleep
                m_Thread.join(); // This call blocks and waits for thread to end
                m_hThread = null;  

            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
用于重新创建线程

 if(m_hThread == null) 
     {   
         m_bThread = true; //while condition of thread
         StartNewThread(); 
     }
在您的实现中,不需要重试Thread.join,它将在第一次尝试时加入,或者它将阻塞,直到线程加入。对于您的案例,只有第一个案例看起来很奇怪,您发现线程已经在运行,这不可能是真的。第二个和第三个对我来说完全有意义,并且像他们应该的那样工作。当用户单击Home按钮时,将调用SurfacedStroyed,并终止线程

只要m_bThread为真,线程就会继续

 while(m_bThread) //b
    {
      // Continuous Thread operations...
    }

m_hThread只是代码中的预线程,m_Thread也是m_hThread,只是这里的一个键入错误。

您应该发布崩溃的堆栈跟踪。重新启动正在运行的线程只会给您一个IllegalStateException,并显示一条消息“thread ready started”。+1表示“通知”线程退出:线程(通常)不应中止,它们需要“自愿”退出。实际上,线程必须退出。棘手的部分是:如果线程处于阻塞等待中,您应该怎么做?(例如,从套接字读取,等待连接…?)在这种情况下,布尔变量是不够的,Java没有select/waitformultiple。但是关于如何处理这个问题还有很多问题是的,类似的事情可能会导致join阻止一切,在这种情况下,surfaceedstroyed需要一些时间才能完成。同时android可能会显示强制关闭对话框。但是,线程的管理也不是一步就能完成的,它应该相应地预先计划好。@rigy73,谢谢你,我已经看过你的代码了,但我不明白m_bThread、m_hThread和m_thread是什么-你能再解释一下吗?再次感谢Hanks@rigy73,不幸的是,它不起作用,当我按Home/Back时,我也会遇到同样的问题(95%的时间,偶尔也可以!)。Logcat(在线程错误之后)说我有一个nullPointerException。我在画布上找到了这个。我已经进行了一些登录,可以肯定的是,canvas在崩溃时返回null,我不明白的是为什么runThread设置为false时run()方法仍然在运行?如果我输入一个日志,它会输出true,直到我点击back/home,然后停止记录,这是我所期望的,但似乎仍然到达记录画布状态的行
 if(m_hThread == null) 
     {   
         m_bThread = true; //while condition of thread
         StartNewThread(); 
     }
 while(m_bThread) //b
    {
      // Continuous Thread operations...
    }