Ожидание завершения работы асинхронной задачи

86

Я новичок в программировании и сомневаюсь.

У меня есть кот, AsyncTaskкоторый я называю RunInBackGround.

и я начинаю этот процесс так:

new RunInBackGround().execute();

Но я хочу подождать, пока этот вызов закончит свое выполнение, прежде чем переходить к другим операторам кода.

Как я могу это сделать?

Есть ли способ для этого?

Бэтмен
источник
2
Смысл AsyncTask в том, что он является асинхронным, то есть не синхронизируется с остальной частью кода.
Gjordis
3
Вы можете использовать его onPostExecute () метода AsyncTask, чтобы получить обратный вызов в своем классе.
DcodeChef
5
вы действительно не хотите ждать, пока он закончится. Вы хотите знать, когда он закончится.
njzk2
3
@DcodeChef - единственный, кто понял, что он хотел в вопросе.
Please_Dont_Bully_Me_SO_Lords
1
Я думаю, что это ответ, который вы ищете stackoverflow.com/questions/13079645/…
user3362415

Ответы:

131

подождите, пока этот вызов не завершит свое выполнение

Вам нужно будет вызвать метод AsyncTask.get () для получения результата и подождать, пока doInBackgroundвыполнение не будет завершено. но это заморозит основной поток пользовательского интерфейса, если вы не вызовете метод get внутри потока .

Чтобы вернуть результат в поток пользовательского интерфейса, запустите AsyncTaskкак:

String str_result= new RunInBackGround().execute().get();
ρяσѕρєя К
источник
3
так как же дождаться результата и не заблокировать основной поток пользовательского интерфейса ?! скажем, код ожидает результата, но в то же время индикатор выполнения продолжает двигаться!
Мухаммад Надери
2
@MuhammadNaderi: Использование AsyncTaskбез getметода и в onPostExecuteметоде AsyncTask вызывается, который предоставляет результаты u в основном потоке пользовательского интерфейса
ρяσѕρєя K
3
конечно, это обходной путь, который я использую уже некоторое время, но иногда мне нужно, чтобы код ждал асинктной задачи, что-то вроде awaitin c#, и, конечно, не блокировал основной поток
Мухаммад Надери,
2
@ ρяσѕρєяK спасибо, миллион спасибо. Вы даже не представляете, сколько я потянул за эту проблему, но с помощью только одного .get () он решил (вы шутите) только один .get () !!!!!
Code_Worm
Как можно использовать AsyncTask и избегать использования get (), чтобы пользовательский интерфейс не зависал?
Arjun Issar,
37

Хотя оптимально было бы неплохо, если бы ваш код мог работать параллельно, возможно, вы просто используете поток, чтобы не блокировать поток пользовательского интерфейса, даже если потоку использования вашего приложения придется его дождаться.

У вас есть 2 варианта;

  1. Вы можете выполнить ожидаемый код в самой AsyncTask. Если это связано с обновлением пользовательского интерфейса (потока), вы можете использовать метод onPostExecute. Он вызывается автоматически, когда ваша фоновая работа завершена.

  2. Если вы по какой-то причине вынуждены делать это в Activity / Fragment / Whatever, вы также можете просто создать собственный слушатель, который вы транслируете из своей AsyncTask. Используя это, у вас может быть метод обратного вызова в вашем Activity / Fragment / Whatever, который вызывается только тогда, когда вы этого хотите: то есть, когда ваша AsyncTask выполняется с тем, чего вы должны были ждать.

Стефан де Брёйн
источник
6
Это потрясающий ответ, должен быть принят. Также вот пример того, как добиться этого с помощью AsyncTasks: stackoverflow.com/questions/12575068/…
Хосе Гонсалес
во втором варианте: пока вы отправляете намерение своему получателю, основной поток будет возобновлен правильно. 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.

К.Деогхаркар
источник
15

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.

Вы можете назвать свою работу по onPostExecute()его звонкам после возвращения изdoInBackground()

onPostExecute - это то, что вам нужно реализовать.

AndroidGeek
источник
1

Я думаю, что самый простой способ - создать интерфейс для получения данных из onpostexecute и запустить Ui из интерфейса:

Создайте интерфейс:

public interface AsyncResponse {
    void processFinish(String output);
}

Тогда в asynctask

@Override
protected void onPostExecute(String data) {
    delegate.processFinish(data);
}

Тогда в вашей основной деятельности

@Override
public void processFinish(String data) {
     // do things

}
Неарюк
источник