简体   繁体   English

您如何等待Java中的线程完成而不冻结GUI?

[英]How do you wait for a thread to finish in Java without freezing the GUI?

I am coding an android game in Eclipse with java. 我正在用Java在Eclipse中编写一个Android游戏。 The main goal is to wait for a thread to finish, then to set a boolean to true. 主要目标是等待线程完成,然后将布尔值设置为true。 The reason is that when a user clicks a button it will only run if the boolean is true. 原因是当用户单击按钮时,只有布尔值为true时,它才会运行。 However, when I call a method, it creates a thread and does its thing, then when it is done, it sets the boolean to true. 但是,当我调用方法时,它会创建一个线程并执行其操作,然后在完成时将布尔值设置为true。 However, it automatically sets the boolean to true while the thread is still running, and so the user can click the button (which messes some things up). 但是,它会在线程仍在运行时自动将布尔值设置为true,因此用户可以单击按钮(这会使事情有些混乱)。 Is there a way to wait for a thread to finish without freezing the screen? 有没有一种方法可以等待线程完成而不冻结屏幕? (thread.join() seems to be freezing it) (thread.join()似乎冻结了它)

Any help is appreciated. 任何帮助表示赞赏。

Seems like you don't really need to wait until the thread is done to continue, the way I see it you only need to be notified once it's done, the simplest approach for it would be passing a "callback listener" object to the thread, and execute it when done, this will let you know that you are ready to continue, OR a better approacch would be an AsyncTask which will allow you to do everything in background and when done you can use the onPostExecute method, hope this helps. 似乎您真的不需要等到线程完成后再继续,就我所知,您只需要在完成后就通知它,最简单的方法是将“回调侦听器”对象传递给线程,并在完成后执行它,这将使您知道您已准备好继续,或者更好的方法是AsyncTask,它允许您在后台执行所有操作,完成后可以使用onPostExecute方法,希望对您有所帮助。

This is the way you create and add a callback to be notified when your thread has completed: 这是创建和添加回调以在线程完成时通知的方式:

//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);

Once the thread completed it will execute the listener and will let you know is done... 一旦线程完成,它将执行侦听器并通知您完成...

Regards! 问候!

Q: Why not set the button to "disabled" when you start the thread ( btn=.setEnabled(false); ), then have the thread set the button to "enabled" just before it exits? 问:为什么在启动线程( btn=.setEnabled(false); )时不将按钮设置为“ disabled”,然后在线程退出之前让线程将按钮设置为“ enabled”?

And yes, calling "thread.join()" (or ANY blocking call) from your UI thread will indeed "freeze" it :) 是的,从您的UI线程调用“ thread.join()”(或任何阻塞调用)确实会“冻结”它:)

PS: Are you using a Java thread, or an Android "Asynch Task"? PS:您使用的是Java线程还是Android的“异步任务”? Here's an excellent tutorial on the latter: 这是关于后者的出色教程:

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

Use an AsyncTask . 使用AsyncTask In onPreExecute() disable your button so the user cannot click it again. onPreExecute()禁用按钮,以便用户无法再次单击它。 In onPostExecute method enable the button again. onPostExecute方法中,再次启用该按钮。 Do the time consuming logic in the doInBackground method. doInBackground方法中执行耗时的逻辑。

try to create a Task extends AsyncTask, override the doinBackground mothed,Then put "time-consuming operation" in it. 尝试创建一个扩展AsyncTask的Task,重写doinBackground方法,然后在其中添加“耗时的操作”。 When your task done,it'll goto "onPostExecute",just use an Interface call back to the Actiity and enable the Button . 完成任务后,它将转到“ onPostExecute”,只需使用接口调用返回到Actiity并启用Button即可。 When you use the AsyncTask you should know that: The Default AsyncTask has got a "pool",System allow 5 instace of AsyncTask ,if you got more than 5 Task,you should create a no limit pool. 当您使用AsyncTask时,您应该知道:默认AsyncTask有一个“池”,系统允许5个AsyncTask实例,如果您有5个以上Task,则应创建一个无限制池。

My English is so so bad,lol. 我的英语太差了,大声笑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM