Ich habe über die Unterschiede leicht verwirrt zwischen Handlers
, AsyncTask
und Threads
in Android. Ich habe hier in StackOverflow einige Blogs und Fragen gelesen.
Handler
sind Hintergrundthreads, mit denen Sie mit der Benutzeroberfläche kommunizieren können. Das Aktualisieren eines Fortschrittsbalkens sollte beispielsweise über erfolgen Handler
. Die Verwendung von Handlern bietet Ihnen den Vorteil MessagingQueues
, dass Sie Nachrichten planen oder mehrere Benutzeroberflächenelemente aktualisieren oder sich wiederholende Aufgaben ausführen möchten.
AsyncTask
sind ähnlich, in der Tat verwenden sie Handler
, werden aber nicht im UI-Thread ausgeführt, sodass es gut zum Abrufen von Daten, zum Beispiel zum Abrufen von Webdiensten, geeignet ist. Später können Sie mit der Benutzeroberfläche interagieren.
Thread
Sie können jedoch nicht mit der Benutzeroberfläche interagieren, bieten "grundlegenderes" Threading und Sie vermissen alle Abstraktionen von AsyncTask
.
Ich möchte jedoch, dass eine Socket-Verbindung in Betrieb genommen wird. Sollte dies in einem Handler oder einem Thread oder sogar einem ausgeführt werdenAsyncTask
? Eine Interaktion mit der Benutzeroberfläche ist überhaupt nicht erforderlich. Macht es einen Unterschied in Bezug auf die Leistung, die ich verwende?
Inzwischen wurde die Dokumentation erheblich verbessert.
Handler
ist kein Thread und führt nichts aus. Es ist nur ein Mittel, um Nachrichten von einem sicher weiterzuleiten Thread an die Nachrichtenwarteschlange eines anderen Threads zu übergeben . Also, in der Regel, (mindestens) zwei Fäden müssen noch erstellt werden , die dann verwenden Sie einen Handler, aber der Handler kann nicht alles selbst ausführen.Antworten:
Als Tutorial zur Android-Hintergrundverarbeitung mit Handlern, AsyncTask und Loadern auf der Vogella-Website heißt es:
Das
Handler
Klasse kann zum Registrieren in einem Thread verwendet werden und bietet einen einfachen Kanal zum Senden von Daten an diesen Thread.Das
AsyncTask
Klasse kapselt die Erstellung eines Hintergrundprozesses und die Synchronisation mit dem Hauptthread. Es unterstützt auch das Berichten des Fortschritts der ausgeführten Aufgaben.Und a
Thread
ist im Grunde das Kernelement des Multithreading, das ein Entwickler mit folgendem Nachteil nutzen kann:Und in Bezug auf die
AsyncTask
, wie die Android-Entwicklerreferenz es ausdrückt:Update Mai 2015: Ich habe eine hervorragende Vortragsreihe zu diesem Thema gefunden.
Wichtig: Wenn Sie an einem Punkt, wo Sie verwenden erwägen
AsyncTask
Ihre Threading Probleme zu lösen, sollten Sie zunächst überprüfenReactiveX/RxAndroid
für ein möglicherweise geeignetere Programmiermuster. Eine sehr gute Quelle, um sich einen Überblick zu verschaffen, ist das beispielhafte Lernen von RxJava 2 für Android .quelle
Wenn wir uns den Quellcode ansehen, werden wir sehen
AsyncTask
und erHandler
ist rein in Java geschrieben. (Es gibt jedoch einige Ausnahmen. Aber das ist kein wichtiger Punkt.)Es gibt also keine Magie in
AsyncTask
oderHandler
. Diese Kurse erleichtern uns das Leben als Entwickler.Beispiel: Wenn Programm A Methode A () aufruft, kann Methode A () in einem anderen Thread mit Programm A ausgeführt werden. Wir können dies anhand des folgenden Codes leicht überprüfen:
Warum sollten wir für einige Aufgaben einen neuen Thread verwenden? Sie können dafür googeln. Viele, viele Gründe, zB: schweres Heben, lang laufende Arbeiten.
Also, was sind die Unterschiede zwischen
Thread
,AsyncTask
undHandler
?AsyncTask
undHandler
sind in Java geschrieben (intern verwenden sie aThread
), also alles, was wir mitHandler
oderAsyncTask
tun können, können wir auch mit a erreichenThread
.Was kann
Handler
und kannAsyncTask
wirklich helfen?Der offensichtlichste Grund ist die Kommunikation zwischen dem Aufruferthread und dem Arbeitsthread. ( Caller-Thread : Ein Thread, der den Worker-Thread aufruft , um einige Aufgaben auszuführen. Ein Caller-Thread muss nicht unbedingt der UI-Thread sein.) Natürlich können wir auf andere Weise zwischen zwei Threads kommunizieren, aber aufgrund der Thread-Sicherheit gibt es viele Nachteile (und Gefahren).
Deshalb sollten wir
Handler
und verwendenAsyncTask
. Diese Klassen erledigen den größten Teil der Arbeit für uns. Wir müssen nur wissen, welche Methoden überschrieben werden müssen.Der Unterschied zwischen
Handler
undAsyncTask
ist: Verwenden Sie diese Option,AsyncTask
wenn der Caller-Thread ein UI-Thread ist . Dies ist, was Android-Dokument sagt:Ich möchte zwei Punkte hervorheben:
1) Einfache Verwendung des UI-Threads (also verwenden, wenn der Aufruferthread UI-Thread ist).
2) Handler müssen nicht manipuliert werden. (bedeutet: Sie können Handler anstelle von AsyncTask verwenden, AsyncTask ist jedoch eine einfachere Option.)
Es gibt viele Dinge in diesem Beitrag, die ich noch nicht gesagt habe, zum Beispiel: Was ist UI-Thread oder warum ist es einfacher. Sie müssen einige Methoden hinter jeder Klasse kennen und verwenden, Sie werden den Grund dafür vollständig verstehen.
@: Wenn Sie das Android-Dokument lesen, sehen Sie:
Diese Beschreibung mag zunächst seltsam erscheinen. Wir müssen nur verstehen, dass jeder Thread jede Nachrichtenwarteschlange hat (wie eine Aufgabenliste), und der Thread nimmt jede Nachricht entgegen und tut dies, bis die Nachrichtenwarteschlange leer ist (genau wie wir unsere Arbeit beenden und ins Bett gehen). Also wann
Handler
kommuniziert wird, gibt es nur eine Nachricht an den Aufruferthread und es wartet auf die Verarbeitung.Kompliziert? Denken Sie daran, dass
Handler
dies sicher mit dem Anrufer-Thread kommunizieren kann.quelle
Nach eingehender Betrachtung ist es einfach.
AsyncTask
::Es ist eine einfache Möglichkeit, einen Thread zu verwenden, ohne etwas über das Java-Thread-Modell zu wissen .
AsyncTask
Gibt verschiedene Rückrufe für den Worker-Thread und den Haupt-Thread.Verwendung für kleine Wartevorgänge wie die folgenden:
Handler
::Wenn wir eine Anwendung in Android installieren, wird ein Thread für diese Anwendung namens MAIN UI Thread erstellt. Alle Aktivitäten werden in diesem Thread ausgeführt. Nach der Android-Single-Thread-Modellregel können wir nicht direkt auf UI-Elemente (Bitmap, Textansicht usw.) für einen anderen in dieser Aktivität definierten Thread zugreifen.
Mit einem Handler können Sie von anderen Hintergrund-Threads aus mit dem UI-Thread kommunizieren. Dies ist in Android nützlich, da Android anderen Threads nicht erlaubt, direkt mit dem UI-Thread zu kommunizieren. Ein Handler kann Message- und Runnable-Objekte senden und verarbeiten, die der MessageQueue eines Threads zugeordnet sind. Jede Handler-Instanz ist einem einzelnen Thread und der Nachrichtenwarteschlange dieses Threads zugeordnet. Wenn ein neuer Handler erstellt wird, ist er an die Thread- / Nachrichtenwarteschlange des Threads gebunden, der ihn erstellt.
Es passt am besten zu:
Thread
::Jetzt ist es Zeit, über den Thread zu sprechen.
Thread ist das übergeordnete Element von
AsyncTask
undHandler
. Beide verwenden intern Thread, was bedeutet, dass Sie auch ein eigenes Thread-Modell wieAsyncTask
und erstellen können. DiesHandler
erfordert jedoch gute Kenntnisse der Java-Implementierung für mehrere Threads .quelle
An
AsyncTask
wird verwendet, um Hintergrundberechnungen durchzuführen und das Ergebnis im UI-Thread zu veröffentlichen (mit optionalen Fortschrittsaktualisierungen). Da Sie sich nicht mit der Benutzeroberfläche befassen, ist aHandler
oderThread
angemessener.Thread
Mit der MethodeHandler
's können Sie einen Hintergrund erzeugen und Nachrichten an Ihren Hauptthread zurückgebenpost
.quelle
Faden
Android unterstützt Standard-Java- Threads . Sie können Standard-Threads und die Tools aus dem Paket "
java.util.concurrent
" verwenden, um Aktionen in den Hintergrund zu stellen. Die einzige Einschränkung besteht darin, dass Sie die Benutzeroberfläche nicht direkt über einen Hintergrundprozess aktualisieren können.Wenn Sie die Benutzeroberfläche von einer Hintergrundaufgabe aus aktualisieren müssen, müssen Sie einige Android-spezifische Klassen verwenden. Sie können die Klasse "
android.os.Handler
" für diese oder die Klasse "" verwendenAsyncTask
" verwendenHandler
Die Klasse "
Handler
" kann die Benutzeroberfläche aktualisieren. Ein Handle bietet Methoden zum Empfangen von Nachrichten und für ausführbare Dateien. Um einen Handler zu verwenden, müssen Sie ihn in Unterklassen unterteilen und überschreibenhandleMessage()
, um Nachrichten zu verarbeiten. Zur VerarbeitungRunable
können Sie die Methode verwenden.post();
Sie benötigen nur eine Instanz eines Handlers in Ihrer Aktivität.Sie können Nachrichten über die Methode
sendMessage(Message msg)
oder postensendEmptyMessage
.AsyncTask
Wenn Sie
Activity
Inhalte herunterladen oder Vorgänge ausführen müssen, die im Hintergrund ausgeführt werdenAsyncTask
können, können Sie eine reaktionsschnelle Benutzeroberfläche verwalten und den Fortschritt für diese Vorgänge für den Benutzer veröffentlichen.Weitere Informationen finden Sie unter diesen Links.
http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/
http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask
quelle
Thread
::Sie können die neue Funktion
Thread
für Hintergrundaufgaben mit langer Laufzeit verwenden, ohne den UI-Thread zu beeinträchtigen. In Java Thread können Sie den UI-Thread nicht aktualisieren.Da normaler Thread für die Android-Architektur nicht sehr nützlich ist, wurden Hilfsklassen für das Threading eingeführt.
Antworten auf Ihre Fragen finden Sie auf der Dokumentationsseite zur Threading-Leistung .
Handler :
Mit A
Handler
können Sie Nachrichten undRunnable
Objekte senden und verarbeiten, die einem Thread zugeordnet sindMessageQueue
. JedeHandler
Instanz ist einem einzelnen Thread und der Nachrichtenwarteschlange dieses Threads zugeordnet.Es gibt zwei Hauptverwendungen für a
Handler
:Planen von Nachrichten und ausführbaren Dateien, die zu einem späteren Zeitpunkt ausgeführt werden sollen;
So stellen Sie eine Aktion in die Warteschlange, die für einen anderen Thread als Ihren eigenen ausgeführt werden soll.
AsyncTask :
AsyncTask
ermöglicht die ordnungsgemäße und einfache Verwendung des UI-Threads. Mit dieser Klasse können Sie Hintergrundoperationen ausführen und Ergebnisse auf dem UI-Thread veröffentlichen, ohne Threads und / oder Handler bearbeiten zu müssen.Nachteile:
Standardmäßig überträgt eine App alle von
AsyncTask
ihr erstellten Objekte in einen einzigen Thread. Daher werden sie seriell ausgeführt, und wie beim Hauptthread kann ein besonders langes Arbeitspaket die Warteschlange blockieren. Verwenden Sie aus diesem Grund AsyncTask, um Arbeitselemente mit einer Dauer von weniger als 5 ms zu verarbeiten .AsyncTask
Objekte sind auch die häufigsten Straftäter für implizite Referenzprobleme.AsyncTask
Objekte bergen auch Risiken im Zusammenhang mit expliziten Verweisen.HandlerThread :
Möglicherweise benötigen Sie einen traditionelleren Ansatz zum Ausführen eines Arbeitsblocks in einem lang laufenden Thread (im Gegensatz zu AsyncTask, der für eine Workload von 5 ms verwendet werden sollte ) und eine gewisse Fähigkeit, diesen Workflow manuell zu verwalten. Ein Handler-Thread ist effektiv ein lang laufender Thread, der die Arbeit aus einer Warteschlange erfasst und bearbeitet.
ThreadPoolExecutor :
Diese Klasse verwaltet die Erstellung einer Gruppe von Threads, legt deren Prioritäten fest und verwaltet, wie die Arbeit auf diese Threads verteilt wird. Wenn die Arbeitslast zunimmt oder abnimmt, dreht sich die Klasse oder zerstört mehr Threads, um sich an die Arbeitslast anzupassen.
Wenn die Arbeitsbelastung höher ist und Single
HandlerThread
nicht ausreicht, können Sie sich entscheidenThreadPoolExecutor
Da keine UI-Interaktion erforderlich ist, können Sie sich nicht dafür entscheiden
AsyncTask
. Normale Threads sind nicht sehr nützlich und daherHandlerThread
die beste Option. Da Sie die Socket-Verbindung aufrechterhalten müssen, ist der Handler im Haupt-Thread überhaupt nicht nützlich. Erstellen Sie einHandlerThread
und erhalten Sie einHandler
vom Looper vonHandlerThread
.Wenn Sie wieder mit dem UI-Thread kommunizieren möchten, können Sie einen weiteren Handler verwenden, um die Antwort zu verarbeiten.
in Ihrem
Runnable
können Sie hinzufügenWeitere Details zur Implementierung finden Sie hier:
Android: Toast in einem Thread
quelle
Meiner Meinung nach sind Threads nicht die effizienteste Methode zum Herstellen von Socket-Verbindungen, bieten jedoch die meisten Funktionen zum Ausführen von Threads. Ich sage das, weil aus Erfahrung heraus das lange Ausführen von Threads dazu führt, dass Geräte sehr heiß und ressourcenintensiv sind. Selbst ein einfaches
while(true)
Telefon heizt ein Telefon in wenigen Minuten auf. Wenn Sie sagen, dass die Interaktion mit der Benutzeroberfläche nicht wichtig ist, ist eine Interaktion möglicherweiseAsyncTask
gut, da sie für langfristige Prozesse ausgelegt ist. Dies ist nur meine Meinung dazu.AKTUALISIEREN
Bitte ignorieren Sie meine obige Antwort! Ich habe diese Frage 2011 beantwortet, als ich mit Android weit weniger Erfahrung hatte als jetzt. Meine obige Antwort ist irreführend und wird als falsch angesehen. Ich lasse es dort, weil viele Leute es unten kommentiert haben, um mich zu korrigieren, und ich habe meine Lektion gelernt.
Es gibt weitaus bessere andere Antworten auf diesen Thread, aber ich werde mir zumindest die richtige Antwort geben. Es ist nichts Falsches daran, ein normales Java zu verwenden
Thread
. Sie sollten jedoch sehr vorsichtig sein, wie Sie es implementieren, da es sehr prozessorintensiv sein kann, wenn Sie es falsch machen (das bemerkenswerteste Symptom kann sein, dass sich Ihr Gerät aufheizt).AsyncTask
s sind ideal für die meisten Aufgaben, die Sie im Hintergrund ausführen möchten (gängige Beispiele sind Festplatten-E / A, Netzwerkaufrufe und Datenbankaufrufe). AllerdingsAsyncTask
sollte s nicht für besonders lange Prozesse verwendet wird, müssen möglicherweise auch nach dem Benutzer Ihre Anwendung geschlossen wird oder in dem Standby setzen ihr Gerät. Ich würde für die meisten Fälle sagen, dass alles, was nicht in den UI-Thread gehört, in einem erledigt werden kannAsyncTask
.quelle
AsyncTask
ist so konzipiert, dass nicht mehr als einige Sekunden im Hintergrund ausgeführt werden (nicht empfohlen für Megabyte des Herunterladens von Dateien vom Server oder für rechenintensive CPU-Aufgaben wie Datei-E / A-Vorgänge). Wenn Sie einen lang laufenden Vorgang ausführen müssen, wird dringend empfohlen, native Java-Threads zu verwenden. Java bietet Ihnen verschiedene Thread-bezogene Klassen, um das zu tun, was Sie brauchen. Verwenden SieHandler
diese Option, um den UI-Thread zu aktualisieren.quelle
quelle
Lassen Sie mich versuchen, die Frage hier mit einem Beispiel zu beantworten :) - MyImageSearch [Bitte beziehen Sie sich hier auf das Bild des Hauptaktivitätsbildschirms - mit einer Bearbeitungstext- / Suchschaltfläche / Rasteransicht]
Beschreibung von MyImageSearch - Sobald der Benutzer die Details in das Feld zum Bearbeiten von Text eingegeben und auf die Schaltfläche "Suchen" geklickt hat, werden Bilder im Internet über die von flickr bereitgestellten Webdienste durchsucht (Sie müssen sich nur dort registrieren, um einen Schlüssel / ein geheimes Token zu erhalten). - Für die Suche senden wir eine HTTP-Anfrage und GET JSON-Daten als Antwort zurück, die die URLs der einzelnen Bilder enthalten, die wir dann zum Laden der Rasteransicht verwenden.
Meine Implementierung - In der Hauptaktivität werde ich eine innere Klasse definieren, die die AsyncTask erweitert, um die HTTP-Anforderung in der doInBackGround-Methode zu senden, die JSON-Antwort abzurufen und meine lokale ArrayList von FlickrItems zu aktualisieren, die ich zum Aktualisieren meiner GridView über den FlickrAdapter verwenden werde (erweitert den BaseAdapter) und rufen Sie adapter.notifyDataSetChanged () in onPostExecute () von AsyncTask auf, um die Rasteransicht neu zu laden. Beachten Sie, dass hier die HTTP-Anforderung ein blockierender Aufruf ist, aufgrund dessen ich sie über die AsyncTask ausgeführt habe. Außerdem kann ich die Elemente im Adapter zwischenspeichern, um die Leistung zu erhöhen, oder sie auf der SDCard speichern. Das Raster, das ich im FlickrAdapter aufblasen werde, enthält in meiner Implementierung eine Fortschrittsanzeige und eine Bildansicht. Unten finden Sie den Code für mainActivity, den ich verwendet habe.
Antwort auf die Frage jetzt - Sobald wir die JSON-Daten zum Abrufen einzelner Bilder haben, können wir die Logik implementieren, die Bilder über Handler oder Threads oder AsyncTask in den Hintergrund zu bringen. Wir sollten hier beachten, dass meine heruntergeladenen Bilder auf der Benutzeroberfläche / im Hauptthread angezeigt werden müssen. Wir können Threads nicht einfach so verwenden, wie sie sind, da sie keinen Zugriff auf den Kontext haben. Im FlickrAdapter die Auswahlmöglichkeiten, die mir einfallen:
Hier der Quellcode:
Ich hoffe, dass meine lange Antwort dazu beiträgt, einige der feineren Details zu verstehen.
quelle
Es hängt davon ab, welche Sie wählen, hängt von der Anforderung ab
Der Handler wird meistens verwendet, um von einem anderen Thread zum Haupt-Thread zu wechseln. Der Handler ist an einen Looper angeschlossen, auf dem er seine ausführbare Aufgabe in die Warteschlange stellt. Wenn Sie sich bereits in einem anderen Thread befinden und zum Hauptthread wechseln, benötigen Sie ein Handle anstelle einer asynchronen Aufgabe oder eines anderen Threads
Wenn ein Handler, der in einem anderen als dem Haupt-Thread erstellt wurde, der kein Looper ist, beim Erstellen des Handles des Threads keinen Fehler ausgibt, muss dieser Thread zu einem Lopper gemacht werden
AsyncTask wird verwendet, um Code für einige Sekunden auszuführen, der im Hintergrundthread ausgeführt wird, und gibt das Ergebnis an den Hauptthread weiter. ** * AsyncTask-Einschränkungen 1. Die Async-Task ist nicht an den Lebenszyklus der Aktivität gebunden und wird auch dann ausgeführt, wenn ihre Aktivität zerstört wird, während der Loader dies nicht tut Diese Einschränkung gilt nicht. 2. Alle Async-Aufgaben verwenden denselben Hintergrundthread für die Ausführung, was sich auch auf die App-Leistung auswirkt
Der Thread wird in der App auch für Hintergrundarbeiten verwendet, hat jedoch keinen Rückruf für den Hauptthread. Wenn die Anforderung für einige Threads anstelle eines Threads geeignet ist und die mehrmals eine Aufgabe ausführen müssen, ist der Thread-Pool-Executor die bessere Option. Beispiel: Laden von Bildern aus mehreren URLs wie gleiten.
quelle
Faden
Wenn Sie eine App starten, wird ein Prozess zum Ausführen des Codes erstellt. Um die Rechenressourcen effizient zu nutzen, können Threads innerhalb des Prozesses gestartet werden, sodass mehrere Aufgaben gleichzeitig ausgeführt werden können. Mit Threads können Sie effiziente Apps erstellen, indem Sie die CPU ohne Leerlaufzeit effizient nutzen.
In Android werden alle Komponenten in einem einzigen Hauptthread ausgeführt. Android-Systemwarteschlangenaufgaben und führen Sie sie einzeln im Hauptthread aus. Wenn lang laufende Aufgaben ausgeführt werden, reagiert die App nicht mehr.
Um dies zu verhindern, können Sie Arbeitsthreads erstellen und Hintergrund- oder Langzeitaufgaben ausführen.
Handler
Da Android ein Single-Thread-Modell verwendet, werden UI-Komponenten nicht threadsicher erstellt. Dies bedeutet, dass nur der von ihm erstellte Thread darauf zugreifen sollte. Dies bedeutet, dass die UI-Komponente nur im Haupt-Thread aktualisiert werden sollte. Da UI-Komponenten auf dem Hauptthread ausgeführt werden, können Aufgaben, die auf Worker-Threads ausgeführt werden, UI-Komponenten nicht ändern. Hier kommt Handler ins Spiel. Der Handler kann mithilfe von Looper eine Verbindung zu einem neuen Thread oder einem vorhandenen Thread herstellen und den darin enthaltenen Code auf dem verbundenen Thread ausführen.
Der Handler ermöglicht die Kommunikation zwischen Threads. Mit dem Handler kann der Hintergrundthread Ergebnisse an ihn senden, und der mit dem Hauptthread verbundene Handler kann die UI-Komponenten im Hauptthread aktualisieren.
AsyncTask
Die von Android bereitgestellte AsyncTask verwendet sowohl Thread als auch Handler, um das Ausführen einfacher Aufgaben im Hintergrund und das Aktualisieren der Ergebnisse vom Hintergrundthread zum Hauptthread zu vereinfachen.
Beispiele finden Sie unter Android-Thread, Handler, Asynctask und Thread-Pools .
quelle
Handler
- ist ein Kommunikationsmedium zwischen Threads. In Android wird es meistens verwendet, um mit dem Hauptthread zu kommunizieren, indem Nachrichten über den Handler erstellt und gesendet werdenAsyncTask
- wird verwendet, um lang laufende Anwendungen in einem Hintergrundthread auszuführen. Mit nAsyncTask
können Sie die Operation in einem Hintergrundthread ausführen und das Ergebnis im Hauptthread der Anwendung abrufen.Thread
- ist ein leichter Prozess, um Parallelität und maximale CPU-Auslastung zu erreichen. In Android können Sie Thread verwenden, um Aktivitäten auszuführen, die die Benutzeroberfläche der App nicht berührenquelle