Android: Quelle est la différence entre Activity.runOnUiThread et View.post?

97

Quelle est la différence entre Activity.runOnUiThreadet View.post, quelqu'un pourrait-il, s'il vous plaît, expliquer?

Alexandre Kulyakhtin
la source

Réponses:

104

Il n'y a pas de réelle différence, sauf que le View.postest utile lorsque vous n'avez pas d'accès direct à l'activité.

Dans les deux cas, si ce n'est pas sur le fil d'interface utilisateur, Handler#post(Runnable)sera appelé en coulisses.

Comme CommonsWare l'a mentionné dans le commentaire, il y a une différence entre les deux - lorsqu'il est appelé sur le thread Ui, Activity#runOnUiThreadappellera la runméthode directement, tandis que View#postle postera runnabledans la file d'attente (par exemple, appelez le Handler#post)

Le point important de l'OMI est que les deux ont le même objectif, et pour quiconque l'utilise, il ne devrait y avoir aucune différence (et la mise en œuvre peut changer à l'avenir).

MByD
la source
70
Une différence: runOnUiThread()vérifie le thread actuel et exécute le Runnableimmédiatement si nous sommes sur le thread principal de l'application. post()met toujours le Runnabledans la file d'attente, quel que soit le thread auquel il est appelé.
CommonsWare
Merci Je peux maintenant voir la différence basée sur votre explication et le commentaire @CommonsWare.
Alexander Kulyakhtin
4
@Ashwin: "Vous avez dit que runOnUiThread () exécute le Runnable immédiatement" - non, je ne l'ai pas fait. Veuillez relire le commentaire. J'ai dit " runOnUiThread()vérifie le thread actuel et exécute le Runnableimmédiatement si nous sommes sur le thread principal de l'application " (emphase ajoutée). "Cela signifie-t-il que ce qui se trouve actuellement sur le thread de l'interface utilisateur est ignoré et que cela a la priorité?" - "ce qui est actuellement sur le fil de l'interface utilisateur" est l' runOnUiThread()appel.
CommonsWare
1
@ barn.gumbl: Dans ce cas, j'ai regardé la source.
CommonsWare
1
Il y a une différence. Publier sur une vue qui n'est pas attachée à une fenêtre ne fera rien. Bien que ce ne soit pas une énorme différence, cela peut provoquer des bugs subtils et est assez ennuyeux à naviguer si vous n'êtes pas conscient de la différence.
dcow
23

Une autre différence entre Activity.runOnUiThread et view.post () est que l'exécutable dans view.post () est appelé après que la vue est attachée à une fenêtre.

pareshgoel
la source
Comment voulez-vous dire montré? Devient visible? Pas du tout appelé sur une vue invisible?
Alexander Kulyakhtin
Correction de l'ambiguïté Alex.
pareshgoel
5
C'est la différence la plus importante à mon humble avis. Beaucoup de gens utilisent view.post () pour exécuter des choses qui doivent être exécutées APRÈS que la vue soit attachée.
Sotti
3
Ce n'est pas vrai. Cela n'a jamais été vrai, mais à un moment donné, le JavaDoc pour View.java a déclaré à tort que "View.post ne fonctionne qu'à partir d'un autre thread lorsque la vue est attachée à une fenêtre". Ce problème a été résolu le 15 octobre 2012, mais il a fallu un certain temps pour pénétrer l'esprit des développeurs Android.
Alex Cohn
@pareshgoel source pour cette différence?
apostleofzion
17

Les deux sont acceptables dans la plupart des situations et pour la plupart, ils sont interchangeables, mais ils sont subtilement différents. La plus grande différence est bien sûr que l'un est disponible à partir d'un Activityet l'autre à partir d'un View. Il y a beaucoup de chevauchements entre ceux-ci, mais parfois dans un, Activityvous n'aurez pas accès à un View, et parfois dans un, Viewvous n'aurez pas accès à un Activity.

L'un des cas extrêmes que j'ai rencontrés avec View.postj'ai mentionné dans une réponse à une autre question SO surView.post : View.postne fonctionne qu'à partir d'un autre thread lorsque le Viewest attaché à une fenêtre. Ceci est rarement un problème, mais peut parfois empêcher l' Runnableexécution du, surtout si vous appelez View.postla onCreateméthode de votre Activity. Une alternative est d'utiliser Handler.postqui est quoi Activity.runOnUiThreadet d' View.postutiliser de toute façon sous les couvertures.

(modifié pour plus de précision, ajouté "à partir d'un autre fil")

Kabuko
la source
1
Il peut échouer lorsqu'il est détaché onCreate()également? Hm, je m'attendrais à ce qu'il soit posté sur le Handlerfourni par ViewRootdans ce cas.
Jens
5
@Jens Oui, j'ai jeté un coup d'œil à la source et je View.postdevrais ajouter le Runnableà une file d'attente pour être exécuté plus tard s'il n'est pas encore attaché. Je n'ai pas creusé beaucoup plus profondément dans la source, mais la documentation dit: "Cette méthode ne peut être invoquée de l'extérieur du thread de l'interface utilisateur que lorsque cette vue est attachée à une fenêtre." Donc, je pense que si c'est sur le fil actuel, alors ce que vous avez dit est vrai, si ce n'est pas le cas, il avale probablement juste le Runnable. Cela s'est certainement produit dans mon code.
kabuko
@kabuko Merci votre réponse le montre d'un autre point. Comment c'est que je ne peux pas accepter plus d'une réponse ne peut pas voir la logique derrière qui
adressera
3
Ce n'est pas vrai. Cela n'a jamais été vrai, mais à un moment donné, le JavaDoc pour View.java a déclaré à tort que "View.post ne fonctionne qu'à partir d'un autre thread lorsque la vue est attachée à une fenêtre". Ce problème a été résolu le 15 octobre 2012, mais il a fallu un certain temps pour pénétrer l'esprit des développeurs Android.
Alex Cohn
0

Une autre différence: postest par vue; runOnUiThreadest par activité.

Cela signifie qu'il sera possible (à l'avenir?) De faire view.getQueue/ activity.getQueueet d'obtenir exactement ce que vous voulez sans votre propre code de suivi ou de filtrage.

Pacerier
la source