Handler vs AsyncTask

128

Ich bin verwirrt, wann man AsyncTask einem Handler vorziehen würde. Angenommen, ich möchte alle n Sekunden einen Code ausführen, der die Benutzeroberfläche aktualisiert. Warum sollte ich einen über den anderen wählen?

Steve
quelle
1
Dies ist bei AsyncTaskLoaders komplizierter geworden. Weitere Informationen finden Sie unter stackoverflow.com/q/7120813/969325 .
Warpzit

Antworten:

75

IMO, AsyncTask wurde geschrieben, um eine bequeme und benutzerfreundliche Möglichkeit zur Hintergrundverarbeitung in Android-Apps zu bieten, ohne sich über die Details auf niedriger Ebene (Threads, Nachrichtenschleifen usw.) Gedanken machen zu müssen. Es bietet Rückrufmethoden, mit denen Sie Aufgaben planen und die Benutzeroberfläche bei Bedarf problemlos aktualisieren können.

Es ist jedoch wichtig zu beachten, dass sich ein Entwickler bei der Verwendung von AsyncTask seinen Einschränkungen unterwirft, die sich aus den Entwurfsentscheidungen ergeben, die der Autor der Klasse getroffen hat. Zum Beispiel habe ich kürzlich herausgefunden, dass die Anzahl der Jobs, die mit AsyncTasks geplant werden können, begrenzt ist.

Handler ist transparenter von beiden und gibt Ihnen wahrscheinlich mehr Freiheit; Wenn Sie also mehr Kontrolle über die Dinge haben möchten, wählen Sie Handler, sonst funktioniert AsynTask einwandfrei.

Samuh
quelle
Das stimmt. Ich habe AsyncTasks für alle Hintergrundvorgänge in meinem Projekt verwendet. Irgendwann erreichte ich das maximale Joblimit, sodass meine Aufgaben erst nach Abschluss eines anderen Jobs begannen. Am Ende musste ich meine gesamte Struktur ändern, um keine Asynctasks mehr zu verwenden und diese Einschränkung nicht zu erreichen.
Tbraun
5
Ab Honeycomb AsyncTaskswerden sie auf einem Thread ausgeführt, also keine Parallelität mehr. Sie können sie weiterhin auf einer parallelen ExecutorImplementierung ausführen .
MrSnowflake
63

Meine Faustregel wäre:

  • Wenn Sie etwas Isoliertes in Bezug auf die Benutzeroberfläche tun, z. B. Daten herunterladen, um sie in einer Liste darzustellen, fahren Sie fort und verwenden Sie sie AsyncTask.

  • Wenn Sie mehrere wiederholte Aufgaben ausführen, z. B. mehrere Bilder ImageViewsherunterladen, die beim Herunterladen angezeigt werden sollen ( z. B. das Herunterladen von Miniaturansichten), verwenden Sie eine Aufgabenwarteschlange mit Handler.

alexanderblom
quelle
Der Handler befindet sich in der API-Ebene 1 und ASYNCTASK in der API-Ebene 3. Wird er um jeden Preis veraltet sein? Ich konzentriere mich darauf, Anwendungen von älteren Versionen auf 2.2 & 2.3 zu
portieren
10
Beides wird in Kürze nicht mehr unterstützt. Der Handler wird niemals veraltet sein, da die Benutzeroberfläche im Wesentlichen darauf aufgebaut ist.
Alexanderblom
Sollten Sie nicht einen Loader verwenden, um Daten für Ihre Benutzeroberfläche zu laden?
Nbarraille
19

Versuchen Sie immer, AsyncTask nach Möglichkeit zu vermeiden, hauptsächlich aus folgenden Gründen:

  • Es wird nicht garantiert, dass AsyncTask ausgeführt wird, da vom System eine ThreadPool-Basis und eine maximale Größe festgelegt werden. Wenn Sie zu viel Asynctask erstellen, werden diese möglicherweise zerstört

  • AsyncTask kann abhängig vom Aktivitätslebenszyklus automatisch beendet werden, auch wenn es ausgeführt wird, und Sie haben keine Kontrolle darüber

  • AsyncTask-Methoden, die auf dem UI-Thread ausgeführt werden, wie onPostExecute, können ausgeführt werden, wenn die Aktivität, auf die sie sich beziehen, nicht mehr sichtbar ist oder sich möglicherweise in einem anderen Layoutstatus befindet, wie nach einer Änderung der Ausrichtung.

Abschließend sollten Sie die UIThread-verknüpften Methoden von AsyncTask nicht verwenden, was der Hauptvorteil ist !!! Darüber hinaus sollten Sie nur unkritische Arbeiten an doInBackground ausführen. Lesen Sie diesen Thread, um weitere Einblicke in diese Probleme zu erhalten:

Ist AsyncTask wirklich konzeptionell fehlerhaft oder fehlt mir nur etwas?

Versuchen Sie abschließend, lieber IntentServices, HandlerThread oder ThreadPoolExecutor anstelle von AsyncTask zu verwenden, wenn eines der oben genannten Probleme ein Problem für Sie darstellt. Sicher, es wird mehr Arbeit erfordern, aber Ihre Anwendung wird sicherer sein.

Typ-a1pha
quelle
Ja, ich habe viel Zeit damit verbracht, viele Anwendungen von AsyncTasks zu bereuen. Sie scheinen großartig zu sein, aber ... so viele Probleme!
Scott Biggs
6
Es tut mir leid, dass ich so stark gegen deine Punkte poste, aber ich kann nicht zulassen, dass dein schlechter Stil Noobies für Android beeinflusst. Punkt eins. Es sollten NICHT so viele Threads ausgeführt werden. Wenn Sie darauf stoßen, ist Ihre Architektur foobar. Punkt 2. Wie um alles in der Welt .. Okay, ja, alles in Android ist ein kostenloses Spiel für den Müllsammler ... Sie würden nur abserd Verhalten wie oben beschrieben sehen, in einigen streng aufgabenmissbräuchlichen Fällen. Punkt 3. Die Verwaltung Ihrer Aufgabe, um nicht unhöflich zu sein, ist eine unerfahrene Fähigkeit. Sie beenden es entweder, wenn Sie onPause aufrufen, oder Sie trennen es ordnungsgemäß und fügen es entsprechend hinzu.
StarWind0
1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html Dies ist alles, was Sie brauchen, um zu lernen, wie man Aufgaben ohne die oben genannten Probleme richtig erledigt (vorausgesetzt, Sie tun nicht so, als würden Sie ein paar hundert Aufgaben
ausspucken
16

Wenn Sie alle x Sekunden eine Berechnung durchführen möchten, sollten Sie wahrscheinlich Runnableeine Handler(mit postDelayed()) Runnableeinplanen, die im aktuellen UI-Thread beginnen sollte. Wenn Sie es in einem anderen Thread starten möchten, verwenden Sie HandlerThread. AsyncTask ist für uns einfacher zu verwenden, aber nicht besser als der Handler.

MrSnowflake
quelle
7

Der Handler ist dem Hauptthread der Anwendung zugeordnet. Es verarbeitet und plant Nachrichten und Runnables, die von Hintergrund-Threads an den App-Haupt-Thread gesendet werden.

AsyncTask bietet eine einfache Methode zum Behandeln von Hintergrundthreads, um die Benutzeroberfläche zu aktualisieren, ohne sie durch zeitaufwändige Vorgänge zu blockieren.

Die Antwort ist, dass beide verwendet werden können, um die Benutzeroberfläche von Hintergrund-Threads zu aktualisieren. Der Unterschied liegt in Ihrem Ausführungsszenario. Sie können den Handler verwenden, um verzögerte Nachrichten zu veröffentlichen oder Nachrichten in einer bestimmten Reihenfolge an die MessageQueue zu senden.

Sie können AsyncTask verwenden, wenn Sie auf einfache und bequeme Weise Parameter zwischen dem Hauptthread der App und dem Hintergrundthread austauschen (und damit die Benutzeroberfläche aktualisieren) möchten.

secretlm
quelle
3
Sie können einen eigenen Handler erstellen, der einem anderen Thread zugeordnet ist.
Aleksejs Mjaliks
Der Handler ist nicht unbedingt an den Hauptthread (UI-Thread) gebunden. Es ist an den Thread gebunden, in dem es instanziiert wurde, und verarbeitet Nachrichten oder ausführbare Nachrichten, die in dieser Thread-Nachrichtenwarteschlange ankommen. Es kann auch Nachrichten- und ausführbare Objekte an diese Thread-Nachrichtenwarteschlange senden.
Azec-pdx
2

AsyncTasksetzt voraus, dass Sie etwas im UI-Thread tun, nachdem einige Hintergrundarbeiten abgeschlossen sind. Auch können Sie es nur einmal ausführen (nach diesem, seinen Status ist FINISHEDund Sie eine Ausnahme erhalten versuchen , es auszuführen einmal mehr). Auch die Flexibilität bei der Verwendung ist nicht viel. Ja, Sie können THREAD_POOL_EXECUTOReine parallele Ausführung verwenden, aber der Aufwand ist möglicherweise nicht wert.

Handlersetzt nichts voraus, außer Runnables und Messages zu behandeln. Es kann auch so oft ausgeführt werden, wie Sie möchten . Sie können frei entscheiden, an welchen Thread es angehängt werden soll, wie es mit anderen Handlern kommuniziert und möglicherweise mit ihnen produziert HandlerThread. Es ist also viel flexibler und für wiederholte Arbeiten geeignet.

Überprüfen Sie andere Art der HandlerBeispiele hier .

Lomza
quelle
0

Sie sind die beste Interviewfrage, die gestellt wird. AsyncTask - Sie werden verwendet, um UI-Threads auszulagern und Aufgaben im Hintergrund auszuführen. Handler - Android Dosent haben eine direkte Kommunikation zwischen der Benutzeroberfläche und dem Hintergrund-Thread. Handler müssen zum Senden von Nachrichten verwendet werden oder über die Nachrichtenwarteschlange ausgeführt werden.

AsyncTasks werden daher verwendet, wenn Aufgaben im Hintergrund ausgeführt werden müssen und Handler für die Kommunikation zwischen einer Benutzeroberfläche und einem Hintergrundthread verwendet werden.

saubhagya das
quelle
0

doInBackground - funktioniert grundsätzlich in einem anderen Thread. onPostExecute - veröffentlicht die Ergebnisse im UI-Thread und sendet intern eine Nachricht an den Handler des Hauptthreads. Dem Haupt-UI-Thread sind bereits ein Looper und ein Handler zugeordnet.

Wenn Sie also eine Hintergrundaufgabe ausführen müssen, verwenden Sie AsyncTask. Wenn jedoch etwas auf der Benutzeroberfläche aktualisiert werden muss, wird der Handler des Hauptthreads verwendet.

Shinoo Goyal
quelle