Android: ¿Cuál es la diferencia entre Activity.runOnUiThread y View.post?

Respuestas:

104

No hay una diferencia real, excepto que View.postes útil cuando no tienes acceso directo a la actividad.

En ambos casos, si no está en el hilo de la interfaz de usuario, Handler#post(Runnable)se llamará detrás de escena.

Como CommonsWare mencionó en el comentario, hay una diferencia entre los dos: cuando se llama en el hilo de Ui, Activity#runOnUiThreadllamará al runmétodo directamente, mientras View#postque publicará el runnableen la cola (por ejemplo, llamará Handler#post)

El punto importante de la OMI es que ambos tienen el mismo objetivo, y para quien lo use, no debería haber diferencia (y la implementación puede cambiar en el futuro).

MByD
fuente
70
Una diferencia: runOnUiThread()comprueba el hilo actual y lo ejecuta Runnableinmediatamente si estamos en el hilo principal de la aplicación. post()siempre pone el Runnableen la cola, sin importar el hilo al que se llame.
CommonsWare
Gracias, ahora puedo ver la diferencia según su explicación y el comentario de @CommonsWare.
Alexander Kulyakhtin
4
@Ashwin: "Dijiste que runOnUiThread () ejecuta Runnable inmediatamente" - no, no lo hice. Vuelva a leer el comentario. Dije " runOnUiThread()comprueba el hilo actual y lo ejecuta Runnableinmediatamente si nos encontramos en el hilo principal de la aplicación " (énfasis agregado). "¿Significa que lo que hay actualmente en el hilo de la interfaz de usuario se ignora y se le da la primera prioridad?" - "lo que hay actualmente en el hilo de la interfaz de usuario" es la runOnUiThread()llamada.
CommonsWare
1
@ barn.gumbl: En este caso, miré la fuente.
CommonsWare
1
No es una diferencia. Publicar en una vista que no está adjunta a una ventana no hará nada. Aunque no es una gran diferencia, esto puede causar errores sutiles y es bastante molesto navegar si no se da cuenta de que existe la diferencia.
dcow
23

Otra diferencia entre Activity.runOnUiThread y view.post () es que el ejecutable en view.post () se llama después de que la vista se adjunta a una ventana.

pareshgoel
fuente
¿Qué quiere decir mostrado? ¿Se vuelve visible? ¿No se llama en absoluto a una vista invisible?
Alexander Kulyakhtin
Alex corrigió la ambigüedad.
pareshgoel
5
Esta es la diferencia más importante en mi humilde opinión. Mucha gente usa view.post () para ejecutar cosas que deben ejecutarse DESPUÉS de adjuntar la vista.
Sotti
3
Esto no es verdad. Esto nunca ha sido cierto, pero en algún momento el JavaDoc para View.java afirmó erróneamente que "View.post solo funciona desde otro hilo cuando la Vista está adjunta a una ventana". Esto se solucionó el 15 de octubre de 2012, pero tomó un tiempo penetrar en la mente de los desarrolladores de Android.
Alex Cohn
@pareshgoel fuente para esta diferencia?
apostleofzion
17

Ambos son aceptables para la mayoría de las situaciones y en su mayor parte son intercambiables, pero son sutilmente diferentes. La mayor diferencia, por supuesto, es que uno está disponible desde un Activityy el otro desde un View. Hay mucha superposición entre ellos, pero a veces en un Activityno tendrá acceso a un View, y otras veces en un Viewno tendrá acceso a un Activity.

Uno de los casos extremos con los View.postque me he encontrado mencioné en una respuesta a otra pregunta de SO sobreView.post : View.postsolo funciona desde otro hilo cuando Viewestá adjunto a una ventana. Esto rara vez es un problema, pero ocasionalmente puede hacer Runnableque nunca se ejecute, especialmente si llama View.postal onCreatemétodo de su Activity. Una alternativa es usar Handler.postcuál es qué Activity.runOnUiThready View.postusar debajo de las cubiertas de todos modos.

(editado para mayor precisión, agregado "de otro hilo")

kabuko
fuente
1
¿Puede fallar también cuando está suelto onCreate()? Hm, espero que se publique en el Handlerproporcionado por ViewRooten ese caso.
Jens
5
@Jens Sí, eché un vistazo a la fuente y View.postdebería agregarlo Runnablea una cola para ejecutarlo más tarde si aún no está adjunto. No he profundizado mucho en la fuente, pero los documentos dicen: "Este método puede invocarse desde fuera del hilo de la interfaz de usuario solo cuando esta Vista está adjunta a una ventana". Así que creo que si está en el hilo actual, entonces lo que dijiste es cierto, si no lo es, probablemente se trague el Runnable. Ciertamente, eso sucedió en mi código.
kabuko
@kabuko Gracias tu respuesta lo muestra desde otro punto. ¿Cómo es que no puedo aceptar más de una respuesta? No veo la lógica detrás de eso se dirigirá al meta foro
Alexander Kulyakhtin
3
Esto no es verdad. Esto nunca ha sido cierto, pero en algún momento el JavaDoc para View.java afirmó erróneamente que "View.post solo funciona desde otro hilo cuando la Vista está adjunta a una ventana". Esto se solucionó el 15 de octubre de 2012, pero tomó un tiempo penetrar en la mente de los desarrolladores de Android.
Alex Cohn
0

Otra diferencia: postes por vista; runOnUiThreades por actividad.

Esto significa que será posible (¿en el futuro?) Hacer view.getQueue/ activity.getQueueobtener exactamente lo que desea sin su propio código de seguimiento o filtrado.

Pacerier
fuente