Ich konvertiere meinen Code von mit Handler
zu AsyncTask
. Letzteres ist großartig in dem, was es tut - asynchrone Aktualisierungen und Verarbeitung der Ergebnisse im Haupt-UI-Thread. Was mir unklar ist, ist, wie man mit Ausnahmen umgeht, wenn etwas durcheinander gerätAsyncTask#doInBackground
.
Ich mache es so, dass ich einen Fehlerhandler habe und Nachrichten an ihn sende. Es funktioniert gut, aber ist es der "richtige" Ansatz oder gibt es eine bessere Alternative?
Ich verstehe auch, dass der Fehlerhandler, wenn ich ihn als Aktivitätsfeld definiere, im UI-Thread ausgeführt werden sollte. Manchmal (sehr unvorhersehbar) erhalte ich jedoch eine Ausnahme, die besagt, dass der von ausgelöste Code Handler#handleMessage
auf dem falschen Thread ausgeführt wird. Sollte ich Activity#onCreate
stattdessen den Fehlerhandler initialisieren ? Das Einfügen runOnUiThread
in Handler#handleMessage
erscheint überflüssig, wird jedoch sehr zuverlässig ausgeführt.
Antworten:
Ich halte an
Throwable
oderException
in derAsyncTask
Instanz selbst fest und mache dann etwas damitonPostExecute()
, sodass meine Fehlerbehandlung die Option hat, einen Dialog auf dem Bildschirm anzuzeigen.quelle
AsyncTask
nach dem Muster , das ich beschreiben.Erstellen Sie ein AsyncResult-Objekt (das Sie auch in anderen Projekten verwenden können).
Geben Sie dieses Objekt von Ihren AsyncTask doInBackground-Methoden zurück und überprüfen Sie es in postExecute. (Sie können diese Klasse als Basisklasse für Ihre anderen asynchronen Aufgaben verwenden.)
Unten finden Sie ein Modell einer Aufgabe, die eine JSON-Antwort vom Webserver erhält.
quelle
super()
an,AsyncTaskResult
wenn die Klasse nichts erweitert?Wenn ich das Bedürfnis habe, Ausnahmen
AsyncTask
richtig zu behandeln, verwende ich dies als Superklasse:Wie üblich überschreiben Sie
doInBackground
Ihre Unterklasse, um Hintergrundarbeiten auszuführen, und lösen bei Bedarf gerne Ausnahmen aus. Sie müssen dann implementierenonPostExecute
(weil es abstrakt ist), und dies erinnert Sie sanft daran, alle Arten von zu behandelnException
, die als Parameter übergeben werden. In den meisten Fällen führen Ausnahmen zu einer Art UI-Ausgabe, daheronPostExecute
ist dies der perfekte Ort, um dies zu tun.quelle
params
weiterleiten, damit es dem Original ähnlicher ist und einfacher zu migrieren ist?new Task("Param").execute()
vornew Task().execute("Param")
.Wenn Sie das RoboGuice-Framework verwenden möchten, das Ihnen weitere Vorteile bietet, können Sie die RoboAsyncTask ausprobieren, die über eine zusätzliche Callback onException () verfügt. Funktioniert wirklich gut und ich benutze es. http://code.google.com/p/roboguice/wiki/RoboAsyncTask
quelle
RoboGuice
noch? Scheint seit 2012 nicht mehr aktualisiert worden zu sein?Ich habe meine eigene AsyncTask-Unterklasse mit einer Schnittstelle erstellt, die Rückrufe für Erfolg und Misserfolg definiert. Wenn also eine Ausnahme in Ihrer AsyncTask ausgelöst wird, wird der Funktion onFailure die Ausnahme übergeben, andernfalls wird dem Rückruf onSuccess Ihr Ergebnis übergeben. Warum Android nichts Besseres zur Verfügung hat, ist mir ein Rätsel.
quelle
Eine umfassendere Lösung für Cagatay Kalan ist unten dargestellt:
AsyncTaskResult
ExceptionHandlingAsyncTask
Beispielaufgabe
quelle
Diese einfache Klasse kann Ihnen helfen
quelle
Eine andere Möglichkeit, die nicht von der Freigabe variabler Mitglieder abhängt, ist die Verwendung von Abbrechen.
Dies ist aus Android-Dokumenten:
Sie können also cancel in der catch-Anweisung aufrufen und sicherstellen, dass onPostExcute niemals aufgerufen wird, sondern onCancelled im UI-Thread aufgerufen wird. So können Sie die Fehlermeldung anzeigen.
quelle
cancel(boolean)
Dies führte zu einem Aufruf vononCancelled()
exist von Anfang an, wurde jedochonCancelled(Result)
in API 11 hinzugefügt .Tatsächlich verwendet AsyncTask FutureTask & Executor. FutureTask unterstützt die Ausnahmekette. Definieren wir zunächst eine Hilfsklasse
Zweitens verwenden wir
quelle
Persönlich werde ich diesen Ansatz verwenden. Sie können einfach die Ausnahmen abfangen und den Stack-Trace ausdrucken, wenn Sie die Informationen benötigen.
Lassen Sie Ihre Aufgabe im Hintergrund einen booleschen Wert zurückgeben.
es ist so:
quelle
Eine andere Möglichkeit wäre,
Object
als Rückgabetyp zu verwenden undonPostExecute()
nach dem Objekttyp zu suchen. Es ist kurz.quelle
Wenn Sie die richtige Ausnahme kennen, können Sie die aufrufen
z.B:
und gehen Sie zu "onProgressUpdate" und führen Sie die folgenden Schritte aus
Dies ist nur in einigen Fällen hilfreich. Sie können auch eine
Global
Exception
Variable behalten und auf die Ausnahme zugreifen.quelle