Android: Was ist der Unterschied zwischen Activity.runOnUiThread und View.post?

96

Was ist der Unterschied zwischen Activity.runOnUiThreadund View.post, könnte jemand bitte erklären?

Alexander Kulyakhtin
quelle

Antworten:

104

Es gibt keinen wirklichen Unterschied, außer dass dies View.posthilfreich ist, wenn Sie keinen direkten Zugriff auf die Aktivität haben.

In beiden Fällen wird, wenn nicht im UI-Thread, Handler#post(Runnable)hinter den Kulissen aufgerufen.

Wie CommonsWare im Kommentar erwähnt, gibt es einen Unterschied zwischen den beiden - wenn es im Ui-Thread aufgerufen wird, Activity#runOnUiThreadwird die runMethode direkt aufgerufen , während View#postdie runnablein der Warteschlange veröffentlicht wird (z. B. call the Handler#post).

Der wichtige Punkt IMO ist, dass beide das gleiche Ziel haben, und für jeden, der es verwendet, sollte es keinen Unterschied geben (und die Implementierung kann sich in Zukunft ändern).

MByD
quelle
70
Ein Unterschied: runOnUiThread()Überprüft den aktuellen Thread und führt den Runnablesofort aus, wenn wir uns zufällig im Hauptanwendungsthread befinden. post()stellt das immer Runnablein die Warteschlange, egal welcher Thread aufgerufen wird.
CommonsWare
Vielen Dank, ich kann jetzt den Unterschied anhand Ihrer Erklärung und des @ CommonsWare-Kommentars erkennen.
Alexander Kulyakhtin
4
@Ashwin: "Sie sagten, runOnUiThread () führt das Runnable sofort aus" - nein, habe ich nicht. Bitte lesen Sie den Kommentar erneut. Ich sagte " runOnUiThread()Überprüft den aktuellen Thread und führt den Runnablesofort aus, wenn wir uns zufällig im Hauptanwendungsthread befinden " (Hervorhebung hinzugefügt). "Bedeutet das, dass alles, was sich gerade im UI-Thread befindet, ignoriert wird und dies erste Priorität erhält?" - "Was auch immer aktuell im UI-Thread ist" ist der runOnUiThread()Aufruf.
CommonsWare
1
@ barn.gumbl: In diesem Fall habe ich mir die Quelle angesehen.
CommonsWare
1
Es gibt einen Unterschied. Das Posten in einer Ansicht, die nicht an ein Fenster angehängt ist, führt zu nichts. Obwohl dies kein großer Unterschied ist, kann dies zu subtilen Fehlern führen und die Navigation ist ziemlich ärgerlich, wenn Sie nicht wissen, dass der Unterschied besteht.
dcow
23

Ein weiterer Unterschied zwischen Activity.runOnUiThread und view.post () besteht darin, dass die ausführbare Datei in view.post () aufgerufen wird, nachdem die Ansicht an ein Fenster angehängt wurde.

Pareshgoel
quelle
Wie meinst du gezeigt? Wird sichtbar? Sie haben überhaupt keine unsichtbare Sicht?
Alexander Kulyakhtin
Die Mehrdeutigkeit von Alex wurde korrigiert.
Pareshgoel
5
Dies ist meiner Meinung nach der wichtigste Unterschied. Viele Leute verwenden view.post (), um Dinge auszuführen, die ausgeführt werden müssen, nachdem die Ansicht angehängt wurde.
Sotti
3
Das ist nicht wahr. Dies war noch nie der Fall, aber irgendwann hat JavaDoc für View.java fälschlicherweise angegeben, dass "View.post nur von einem anderen Thread aus funktioniert, wenn die Ansicht an ein Fenster angehängt ist". Dies wurde am 15. Oktober 2012 behoben , aber es dauerte eine Weile, bis die Köpfe der Android-Entwickler durchdrungen waren.
Alex Cohn
@pareshgoel Quelle für diesen Unterschied?
Apostelofzion
17

Entweder sind akzeptabel für die meisten Situationen und zum größten Teil sie austauschbar sind, aber sie sind auf subtile Weise anders. Der größte Unterschied ist natürlich, dass einer von einem Activityund der andere von einem erhältlich ist View. Es gibt viele Überschneidungen zwischen diesen, aber manchmal haben Sie in einem Activitykeinen Zugriff auf ein View, und manchmal haben Sie in einem Viewkeinen Zugriff auf ein Activity.

Einer der Randfälle, auf die ich gestoßen View.postbin, wurde in einer Antwort auf eine andere SO-Frage erwähntView.post : Funktioniert View.postnur von einem anderen Thread aus, wenn der Viewan ein Fenster angehängt ist. Dies ist selten ein Problem, kann jedoch gelegentlich dazu Runnableführen, dass das Programm nie ausgeführt wird, insbesondere wenn Sie View.postdie onCreateMethode Ihres aufrufen Activity. Eine Alternative ist zu verwenden, Handler.postwas was ist Activity.runOnUiThreadund View.postunter der Decke zu verwenden.

(aus Genauigkeitsgründen bearbeitet, "aus einem anderen Thread" hinzugefügt)

Kabuko
quelle
1
Kann es auch scheitern, wenn onCreate()es nicht angeschlossen ist? Hm, ich würde erwarten, dass es in diesem Fall an die von Handlergeliefert ViewRootwird.
Jens
5
@Jens Ja, ich habe einen Blick auf die Quelle geworfen und View.postsollte die Runnablezu einer Warteschlange hinzufügen, die später ausgeführt werden soll, wenn sie noch nicht angehängt ist. Ich habe nicht viel tiefer in die Quelle gegraben, aber die Dokumente sagen: "Diese Methode kann nur von außerhalb des UI-Threads aufgerufen werden, wenn diese Ansicht an ein Fenster angehängt ist." Also ich denke, wenn es auf dem aktuellen Thread ist, dann ist das, was du gesagt hast, wahr, wenn es nicht ist, dann schluckt es wahrscheinlich nur das Runnable. Ich habe das sicherlich in meinem Code erlebt.
Kabuko
@kabuko Vielen Dank, dass Ihre Antwort es von einem anderen Punkt zeigt. Wie es ist, kann ich nicht mehr als 1 Antwort akzeptieren, kann keine Logik dahinter sehen, die das Meta-Forum
ansprechen
3
Das ist nicht wahr. Dies war noch nie der Fall, aber irgendwann hat JavaDoc für View.java fälschlicherweise angegeben, dass "View.post nur von einem anderen Thread aus funktioniert, wenn die Ansicht an ein Fenster angehängt ist". Dies wurde am 15. Oktober 2012 behoben , aber es dauerte eine Weile, bis die Köpfe der Android-Entwickler durchdrungen waren.
Alex Cohn
0

Ein weiterer Unterschied: postist pro Ansicht; runOnUiThreadist pro Aktivität.

Dies bedeutet, dass es (in Zukunft?) Möglich sein wird , genau das zu tun view.getQueue/ zu activity.getQueuebekommen, was Sie wollen, ohne Ihren eigenen Tracking- oder Filtercode.

Pacerier
quelle