Чекаючи, поки асинхронне завдання закінчить свою роботу


85

Я дуже новачок у програмуванні і маю деякі сумніви.

У мене є 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

Відповіді:


130

зачекайте, поки цей виклик закінчить своє виконання

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

Щоб повернути результат у потоці інтерфейсу користувача, почніть AsyncTaskяк:

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

3
так як дочекатися результату і не заблокувати основний потік інтерфейсу?! скажімо, код чекає результату, але тим часом індикатор прогресу продовжує котитися!
Мухаммед Надері

2
@MuhammadNaderi: Викликається використання AsyncTaskбез getметоду та в onPostExecuteметоді AsyncTask , які забезпечують результати у головній темі інтерфейсу користувача
ρяσѕρєя K

3
впевнений, це обхідний шлях, який я використовую вже деякий час, але іноді мені потрібно, щоб код почекав асинктаск, щось на кшталт awaitin c#, і, звичайно, не заблокував основний потік
Мухаммад Надері

2
@ ρяσѕρєяK дякую, дякую мільйону. ви не уявляєте, скільки я витягнув волосся за цю проблему, однак лише одним .get () це вирішено (ви жартуєте) лише одним .get () !!!!!
Code_Worm

Як можна використовувати AsyncTask і уникати використання get (), щоб уникнути замерзання інтерфейсу?
Арджун Іссар

36

Хоча оптимально було б непогано, якщо б ваш код міг працювати паралельно, це може бути так, якщо ви просто використовуєте потік, щоб ви не блокували потік інтерфейсу, навіть якщо потоку використання вашої програми доведеться чекати на це.

Тут у вас є майже 2 варіанти;

  1. Ви можете виконати код, який ви хочете зачекати, в самому AsyncTask. Якщо це пов’язано з оновленням інтерфейсу користувача (потоку), ви можете використовувати метод onPostExecute. Це викликається автоматично, коли закінчується фонова робота.

  2. Якщо ви з якихось причин змушені це робити в Activity / Fragment / Whatever, ви також можете просто зробити собі власного слухача, якого ви транслюєте з вашого AsyncTask. Використовуючи це, ви можете мати метод зворотного виклику у вашому Activity / Fragment / будь-якому, що викликається лише тоді, коли ви цього хочете: тобто, коли ваш 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 - це те, що вам потрібно реалізувати.


1

Я думаю, що найпростіший спосіб - це створити інтерфейс для отримання даних з onpostexecute і запустити інтерфейс користувача з інтерфейсу:

Створити інтерфейс:

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

Потім в асинктаск

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

Тоді у вас основна діяльність

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

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.