如何在不冻结GUI的情况下等待线程完成Java?

时间:2013-12-27 01:55:21

标签: java android multithreading

我正在使用java编写Eclipse游戏中的Android游戏。主要目标是等待线程完成,然后将布尔值设置为true。原因是,当用户单击按钮时,只有在布尔值为true时才会运行。但是,当我调用一个方法时,它会创建一个线程并执行它的操作,然后当它完成时,它将布尔值设置为true。但是,它在线程仍在运行时自动将布尔值设置为true,因此用户可以单击按钮(这会使某些事情变得混乱)。有没有办法等待线程完成而不冻结屏幕? (thread.join()似乎冻结了它)

感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

好像你真的不需要等到线程完成才能继续,我看到它的方式你只需要在完成后得到通知,最简单的方法就是传递一个“回调监听器”对象到线程,并在完成后执行它,这将让你知道你已准备好继续,或者更好的认可将是一个AsyncTask,它将允许你在后台完成所有工作,完成后你可以使用onPostExecute方法,希望这有帮助。

这是您创建和添加回调的方式,以便在您的线程完成时收到通知:

//Create your callback listener interface...
public interface MyThreadListener{
    public void threadFinished();
}

//This is the method that runs some functionality in a separate thread
public void executeTaskInSeparateThread(final MyThreadListener listener){
    new Thread(new Runnable() {

        @Override
        public void run() {
            // DO your long task here...

            //Notify when done before leaving run method...
            listener.threadFinished();
        }
    }).start();
}

//Use it like this
//Create the implementation of the listener you want (this is something like what you usually do for buttons or any other android listener)
MyThreadListener listener = new MyThreadListener() {

    @Override
    public void threadFinished() {
        //Do whatever you want when notified...
        //NOTE: This method will be called on a separated thread too, you cannot modify views...
    }
};
executeTaskInSeparateThread(listener);

一旦线程完成,它将执行监听器并让你知道完成...

问候!

答案 1 :(得分:2)

问:为什么不在启动线程(btn=.setEnabled(false);)时将按钮设置为“禁用”,然后让线程在退出之前将按钮设置为“已启用”?

是的,从你的UI线程调用“thread.join()”(或 ANY 阻塞调用)确实会“冻结”它:)

PS: 您使用的是Java线程还是Android“Asynch Task”?这是关于后者的优秀教程:

http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html

答案 2 :(得分:2)

使用AsyncTask。在onPreExecute()中禁用您的按钮,以便用户无法再次单击它。 在onPostExecute方法中再次启用该按钮。在doInBackground方法中执行耗时的逻辑。

答案 3 :(得分:0)

尝试创建一个Task extends AsyncTask,覆盖doinBackground mothed,然后在其中加入“耗时的操作”。当你的任务完成后,它将转到“onPostExecute”,只需使用一个接口回调到Actiity并启用按钮。当您使用AsyncTask时,您应该知道:Default AsyncTask有一个“池”,System允许5个AsyncTask实例,如果你有超过5个Task,你应该创建一个无限制池。

我的英语太糟糕了,哈哈。