Warten, bis die asynchrone Aufgabe ihre Arbeit beendet hat

82

Ich bin sehr neu in der Programmierung und habe einige Zweifel.

Ich habe eine, AsyncTaskdie ich als nenne RunInBackGround.

und ich beginne diesen Prozess wie:

new RunInBackGround().execute();

Ich möchte jedoch warten, bis die Ausführung dieses Aufrufs abgeschlossen ist, bevor ich mit den anderen Codeanweisungen fortfahre.

Wie kann ich das machen?

Gibt es einen Weg dafür?

Batman
quelle
2
Der Punkt von AsyncTask ist, dass es asynchron ist, was bedeutet, dass es nicht mit dem Rest des Codes synchronisiert ist.
Gjordis
3
Sie können die Methode onPostExecute () von AsyncTask verwenden, um einen Rückruf in Ihrer Klasse zu erhalten.
DcodeChef
5
du willst nicht wirklich warten, bis es fertig ist. Was Sie wollen, ist zu wissen, wann es fertig ist.
NJZK2
3
@DcodeChef ist der einzige, der verstanden hat, was er in der Frage wollte.
Please_Dont_Bully_Me_SO_Lords
1
Ich denke, dies ist die Antwort, die Sie suchen. Stackoverflow.com/questions/13079645/…
user3362415

Antworten:

129

Warten Sie, bis dieser Aufruf beendet ist

Sie müssen die AsyncTask.get () -Methode aufrufen , um das Ergebnis zurückzugewinnen, und warten, bis die doInBackgroundAusführung nicht abgeschlossen ist. aber dies wird Haupt UI - Thread einfrieren , wenn Sie Anruf nicht Methode in einem Thema bekommen .

Um das Ergebnis wieder im UI-Thread zu erhalten, beginnen Sie AsyncTaskwie folgt :

String str_result= new RunInBackGround().execute().get();
ρяσssρєя K.
quelle
3
Wie kann man also auf das Ergebnis warten und den Haupt-UI-Thread nicht sperren lassen ?! Sagen wir, der Code wartet auf das Ergebnis, aber in der Zwischenzeit rollt der Fortschrittsbalken weiter!
Muhammad Naderi
2
@ MuhammadNaderi: Verwendung AsyncTaskohne getMethode und in AsyncTask wird eine onPostExecuteMethode aufgerufen, die u Ergebnisse auf dem Haupt-UI-Thread
liefert
2
Sicher, dies ist eine Problemumgehung, die ich schon seit einiger Zeit verwende, aber manchmal muss der Code auf die Asynctask warten, so etwas wie awaitin c#, und natürlich nicht den Haupt-Thread sperren
Muhammad Naderi
2
@ ρяσsρєяK danke, danke eine Million. Sie haben keine Ahnung, wie sehr ich Haare über dieses Problem gezogen habe, aber mit nur einem .get () löste es (Sie scherzen mich) nur ein .get () !!!!!
Code_Worm
Wie können Sie die AsyncTask verwenden und die Verwendung von get () vermeiden, um ein Einfrieren der Benutzeroberfläche zu vermeiden?
Arjun Issar
36

Obwohl es optimal wäre, wenn Ihr Code parallel ausgeführt werden kann, kann es sein, dass Sie einfach einen Thread verwenden, damit Sie den UI-Thread nicht blockieren, selbst wenn der Nutzungsfluss Ihrer App darauf warten muss.

Sie haben hier so ziemlich zwei Möglichkeiten;

  1. Sie können den Code, auf den Sie warten möchten, in der AsyncTask selbst ausführen. Wenn es um die Aktualisierung der Benutzeroberfläche (Thread) geht, können Sie die onPostExecute-Methode verwenden. Dies wird automatisch aufgerufen, wenn Ihre Hintergrundarbeit erledigt ist.

  2. Wenn Sie aus irgendeinem Grund gezwungen sind, dies in Aktivität / Fragment / Was auch immer zu tun, können Sie sich auch einfach zu einem benutzerdefinierten Listener machen, den Sie von Ihrer AsyncTask aus senden. Auf diese Weise können Sie eine Rückrufmethode in Ihrer Aktivität / Fragment / Was auch immer haben, die nur aufgerufen wird, wenn Sie es möchten: auch bekannt als, wenn Ihre AsyncTask mit dem fertig ist, worauf Sie warten mussten.

Stefan de Bruijn
quelle
6
Dies ist eine großartige Antwort, sollte die akzeptierte sein. Auch hier ist ein Beispiel, wie dies mit AsyncTasks erreicht werden kann: stackoverflow.com/questions/12575068/…
Jose Gonzalez
In Ihrer zweiten Option, In der Zwischenzeit, wenn Sie die Absicht auf Ihren Empfänger werfen, wird der Haupt-Thread richtig fortgesetzt. OP braucht das nicht.
LincyTonita
16

Fügen AsyncTaskSie in Ihrem ProgressDialog Folgendes hinzu:

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

Sie können die Nachricht onPreExecute()wie folgt einstellen :

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

und in Ihrer onPostExecute(Void result)Methode entlassen Sie Ihre ProgressDialog.

KDeogharkar
quelle
15

AsyncTask hat vier Methoden.

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.

Sie können Ihre Arbeit aufrufen, onPostExecute()nachdem Sie von zurückgekehrt sinddoInBackground()

onPostExecute ist das, was Sie implementieren müssen.

AndroidGeek
quelle
1

Ich denke, der einfachste Weg ist, eine Schnittstelle zu erstellen, um die Daten von onpostexecute abzurufen und die Benutzeroberfläche von der Schnittstelle aus auszuführen:

Erstellen Sie eine Schnittstelle:

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

Dann in asynctask

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

Dann in Ihrer Haupttätigkeit

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

}
Nearyuk
quelle