等待异步任务完成其工作

94

我对编程非常不熟悉,有一些疑问。

我有一个名为RunInBackgroundAsyncTask,我将其称为。

我通过以下方式启动此进程:

new RunInBackGround().execute();

但是我希望在执行完这个调用之前等待,然后再继续执行代码中的其他语句。

我该怎么做呢?

有什么方法可以做到吗?


2
AsyncTask 的重点在于它是异步的,这意味着它与代码的其余部分不同步。 - Gjordis
4
您可以在AsyncTask的onPostExecute()方法中获取回调,在您的类中使用该方法。 - DcodeChef
5
你并不真正想要等到它完成。你想知道的是它何时完成。 - njzk2
4
@DcodeChef 是唯一一个理解问题中他想要的东西的人。 - NaN
1
我认为这是你要找的答案 https://dev59.com/TGcs5IYBdhLWcg3wLAyf - user3362415
正如@DcodeChef所说,在继承AsyncTask的类中,您可以使用方法onPostExecute(),在外部类中,您可以引用AsyncTask并调用其方法Get()或GetAsync()来等待任务的同步/异步结果。 - Windgate
5个回答

140

等待此调用执行完毕

您需要调用AsyncTask.get()方法来获得结果,并等待doInBackground执行完成。但是,如果您不在线程内调用get方法,则会冻结主UI线程。

要在UI线程中获取结果,请启动AsyncTask

String str_result= new RunInBackGround().execute().get();

4
如何等待结果而不被主 UI 线程锁定?代码在等待结果的同时,进度条仍然保持滚动状态! - Muhammad Naderi
3
在不使用get方法的情况下使用AsyncTask,并且在AsyncTask中调用onPostExecute方法,该方法会在主UI线程上提供结果。 - ρяσѕρєя K
3
当然,这是我现在一直在使用的解决方法,但有时我需要代码等待asynctask完成,类似于c#中的await,而不会锁定主线程。 - Muhammad Naderi
2
@ρяσѕρєяK 谢谢你,万分感谢。你不知道我为这个问题抓狂了多久,但只用了一个 .get() 就解决了(你在开玩笑吧)只有一个 .get() !!!!! - Code_Worm
@ArjunIssar:那你只需要调用 RunInBackGround().execute(); 并使用 onPostExecute 方法获取 AsyncTask 结果即可。 - ρяσѕρєя K
显示剩余2条评论

38

虽然最理想的情况是您的代码可以并行运行,但有时候您可能只是使用一个线程,以便不会阻塞UI线程,即使您的应用程序使用流程必须等待它。

在这里,您基本上有两个选择;

  1. 您可以在AsyncTask本身中执行您想要等待的代码。如果涉及更新UI(线程), 您可以使用onPostExecute方法。当后台工作完成时,此方法会自动调用。

  2. 如果由于某种原因而被迫在Activity/Fragment/其他组件中执行,您也可以创建自定义监听器,从AsyncTask中广播。通过使用这个方法,您可以在Activity/Fragment/其他组件中拥有一个回调函数,只有当您想要的时候才会调用它:即当您的AsyncTask完成了您需要等待的任务。


6
这是一个很棒的答案,应该被采纳。同时这里提供了一个使用AsyncTasks实现的示例:https://dev59.com/emcs5IYBdhLWcg3wym_D - Jose Gonzalez
在你的第二个选项中,同时你向接收器抛出意图,主线程将会被恢复。但 OP 不需要这样做。 - LincyTonita

16

在你的 AsyncTask 中添加一个 ProgressDialog,例如:

private final ProgressDialog dialog = new ProgressDialog(YourActivity.this);

你可以在onPreExecute()方法中设置消息,如下所示:

this.dialog.setMessage("Processing..."); 
this.dialog.show();

在你的onPostExecute(Void result)方法中关闭你的ProgressDialog


ProgressDialog早在几年前就已经被弃用了,不要浪费时间使用它,因为它会在主线程中创建一个无法打破的循环,导致应用程序出现内存泄漏,甚至危险。 - Windgate
AsyncTask已经被弃用了。 - Paranoid Android

16

AsyncTask有四个方法...

onPreExecute  -- for doing something before calling background task in Async

doInBackground  -- operation/Task to do in Background

onProgressUpdate  -- it is for progress Update

onPostExecute  -- this method calls after asyncTask return from doInBackground.

doInBackground()方法返回后,您可以调用onPostExecute()方法。

因此您需要实现onPostExecute方法。


1
我认为最简单的方法是创建一个接口来从onpostexecute获取数据并从接口运行Ui:
创建一个接口:
public interface AsyncResponse {
    void processFinish(String output);
}

然后在异步任务中。
@Override
protected void onPostExecute(String data) {
    delegate.processFinish(data);
}

然后在你的主活动中。
@Override
public void processFinish(String data) {
     // do things

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接