In meiner Aktivität verwende ich eine Klasse, die sich von AsyncTask erstreckt, und einen Parameter, der eine Instanz dieser AsyncTask ist. Wenn ich anrufe, ist mInstanceOfAT.execute("")
alles in Ordnung. Die App stürzt jedoch ab, wenn ich eine Aktualisierungstaste drücke, die die AsyncTask erneut aufruft (falls der Netzwerkjob nicht funktioniert hat). Ursache erscheint dann eine Ausnahme, die besagt
Aufgabe kann nicht ausgeführt werden: Die Aufgabe wurde bereits ausgeführt (eine Aufgabe kann nur einmal ausgeführt werden).
Ich habe versucht, cancel (true) für die Instanz der Asyctask aufzurufen, aber es funktioniert auch nicht. Die einzige Lösung besteht bisher darin, neue Instanzen der Asyntask zu erstellen. Ist das der richtige Weg?
Vielen Dank.
quelle
Die Gründe für Fire-and-Forget-Instanzen von ASyncTask sind in Steve Prentices Antwort ziemlich detailliert beschrieben. Obwohl Sie sich darauf beschränken, wie oft Sie eine ASyncTask ausführen, können Sie tun, was Sie möchten, während der Thread ausgeführt wird. .
Fügen Sie Ihren ausführbaren Code in eine Schleife in doInBackground () ein und verwenden Sie eine gleichzeitige Sperre, um jede Ausführung auszulösen. Sie können die Ergebnisse mit PublishProgress () / onProgressUpdate () abrufen .
Beispiel:
Dies ist natürlich etwas komplizierter als die herkömmliche Verwendung von ASyncTask, und Sie geben die Verwendung von PublishProgress () für die tatsächliche Fortschrittsberichterstattung auf. Wenn der Speicher jedoch Ihr Anliegen ist, stellt dieser Ansatz sicher, dass zur Laufzeit nur eine ASyncTask im Heap verbleibt.
quelle
IllegalMonitorStateException
inrunAgain
(genannt vononProgressUpdate
) sehen diese Antwort: stackoverflow.com/a/42646476/2711811 . Es legt nahe (und hat für mich funktioniert), dass diesignal()
Bedürfnisse von einemlock
/ umgeben sein müssenunlock
. Dies hängt möglicherweise mit dem Zeitpunkt despublishProgress
Anrufs zusammenonProgressUpdate
.Ich hatte das gleiche Problem. In meinem Fall habe ich eine Aufgabe, die ich in
onCreate()
und in erledigen möchteonResume(
. Also habe ich meine Asynctask statisch gemacht und die Instanz daraus abgerufen. Jetzt haben wir immer noch das gleiche Problem.Was ich in onPostExecute () getan habe, ist Folgendes:
Denken Sie daran, dass ich in der statischen Methode getInstance einchecke, dass meine Instanz nicht null ist, sonst erstelle ich sie:
Die Methode in postExecute leert die Instanz und erstellt sie neu. Dies kann natürlich auch außerhalb der Klasse erfolgen.
quelle
Ich habe meine Rotationsaufgaben statisch gemacht, wodurch ich sie bei Rotationsänderungen an UI-Threads anhängen, trennen und wieder anhängen konnte. Um jedoch auf Ihre Frage zurückzukommen, erstelle ich ein Flag, um festzustellen, ob der Thread ausgeführt wird. Wenn Sie den Thread neu starten möchten, überprüfe ich, ob die Rotationsaufgabe ausgeführt wird, wenn ich auf eine Warnung stoße. Wenn dies nicht der Fall ist, mache ich es null und erstelle dann ein neues, das den angezeigten Fehler umgeht. Außerdem habe ich nach erfolgreichem Abschluss die abgeschlossene rotationsbewusste Aufgabe auf Null gesetzt, damit sie wieder einsatzbereit ist.
quelle
Ja, es ist wahr, der Doc sagt, dass nur eine Asyntask ausgeführt werden kann.
Jedes Mal, wenn Sie es verwenden müssen, müssen Sie Folgendes tun:
quelle