Ich führe Remote-Operationen zum Abrufen von Audiodateien und zur Wiedergabe von Audiodateien in einem Hintergrundthread mit aus AsyncTask
. Cancellable
Für die Zeit, in der der Abrufvorgang ausgeführt wird, wird ein Fortschrittsbalken angezeigt.
Ich möchte den AsyncTask
Lauf abbrechen / abbrechen , wenn der Benutzer den Vorgang abbricht (sich dagegen entscheidet). Was ist der ideale Weg, um einen solchen Fall zu behandeln?
android
android-asynctask
Samuh
quelle
quelle
while(running)
mitwhile(!isCancelled())
wie andere gesagt haben hier in den Kommentaren.Wenn Sie Berechnungen durchführen :
isCancelled()
regelmäßig überprüfen .Wenn Sie eine HTTP-Anfrage stellen :
HttpGet
oderHttpPost
irgendwo (z. B. ein öffentliches Feld).cancel
Anruf anrequest.abort()
. Dies wird dazu führen,IOException
dass Sie in Ihre geworfen werdendoInBackground
.In meinem Fall hatte ich eine Connector-Klasse, die ich in verschiedenen AsyncTasks verwendet habe. Um es einfach zu halten, habe ich
abortAllRequests
dieser Klasse eine neue Methode hinzugefügt und diese Methode direkt nach dem Aufruf aufgerufencancel
.quelle
HttpGet.abort()
von einem Hintergrund-Thread anrufen , sonst erhalten Sie eineandroid.os.NetworkOnMainThreadException
.cancel(true)
die Anfrage nicht unterbrechen? Aus der Dokumentation:If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
HttpURLConnection.disconnect();
cancel(true)
. Ich habe es benutzt und es funktioniert.Die Sache ist, dass der Aufruf von AsyncTask.cancel () nur die Funktion onCancel in Ihrer Aufgabe aufruft. Hier möchten Sie die Abbruchanforderung bearbeiten.
Hier ist eine kleine Aufgabe, mit der ich eine Aktualisierungsmethode auslöse
quelle
running
Flagge erstellt werden. AsyncTask verfügt über ein internes Flag, das gesetzt wird, wenn die Aufgabe abgebrochen wurde. Ersetzenwhile (running)
durchwhile (!isCancelled())
. developer.android.com/reference/android/os/… In diesem einfachen Fall müssen Sie also nichtonCancelled()
überschreiben.Einfach: Verwenden Sie keine
AsyncTask
.AsyncTask
ist für kurze Vorgänge ausgelegt, die schnell enden (mehrere zehn Sekunden) und daher nicht abgebrochen werden müssen. "Wiedergabe von Audiodateien" ist nicht qualifiziert. Sie benötigen nicht einmal einen Hintergrund-Thread für die normale Wiedergabe von Audiodateien.quelle
onPostExecute()
, ob Sie mit der Arbeit fortfahren sollten.Die einzige Möglichkeit, dies zu tun, besteht darin, den Wert der Methode isCancelled () zu überprüfen und die Wiedergabe zu stoppen, wenn true zurückgegeben wird.
quelle
So schreibe ich meine AsyncTask.
Der entscheidende Punkt ist das Hinzufügen von Thread.sleep (1).
quelle
Unsere globale AsyncTask-Klassenvariable
Und KEYCODE_BACK-Aktion, die AsyncTask unterbricht
Für mich geht das.
quelle
Ich möchte meine asynchronen Aufgaben nicht
cancel(true)
unnötig unterbrechen, da sie möglicherweise Ressourcen freigeben müssen, z. B. das Schließen von Sockets oder Dateistreams, das Schreiben von Daten in die lokale Datenbank usw. Andererseits habe ich Situationen erlebt, in denen die Die asynchrone Aufgabe weigert sich, sich zeitweise selbst zu beenden, zum Beispiel manchmal, wenn die Hauptaktivität geschlossen wird und ich die asynchrone Aufgabe auffordere, sie innerhalb deronPause()
Methode der Aktivität zu beenden . Es geht also nicht nur darum anzurufenrunning = false
. Ich muss mich für eine gemischte Lösung entscheiden: Beide rufen aufrunning = false
, geben der asynchronen Aufgabe einige Millisekunden Zeit und beenden dann entwedercancel(false)
odercancel(true)
.Als Nebenergebnis wird nach
doInBackground()
Abschluss manchmal dieonCancelled()
Methode aufgerufen, und manchmalonPostExecute()
. Zumindest die Beendigung der asynchronen Aufgabe ist jedoch garantiert.quelle
In Bezug auf Yanchenkos Antwort vom 29. April '10: Die Verwendung eines "while (running)" - Ansatzes ist ordentlich, wenn Ihr Code unter "doInBackground" bei jeder Ausführung der AsyncTask mehrmals ausgeführt werden muss. Wenn Ihr Code unter 'doInBackground' nur einmal pro Ausführung der AsyncTask ausgeführt werden muss, wird durch das Umschließen Ihres gesamten Codes unter 'doInBackground' in eine 'while (running)' - Schleife nicht verhindert, dass der Hintergrundcode (Hintergrundthread) ausgeführt wird, wenn der AsyncTask selbst wird abgebrochen, da die Bedingung 'while (running)' erst ausgewertet wird, wenn der gesamte Code in der while-Schleife mindestens einmal ausgeführt wurde. Sie sollten daher entweder (a.) Ihren Code unter 'doInBackground' in mehrere 'während (laufende)' Blöcke aufteilen oder (b.) Zahlreiche 'isCancelled' ausführen.https://developer.android.com/reference/android/os/AsyncTask.html .
Für Option (a.) Kann man daher Yanchenkos Antwort wie folgt ändern:
Für Option (b.) Sieht Ihr Code in 'doInBackground' ungefähr so aus:
quelle