2012-06-26 12 views
43

para actualizar la interfaz gráfica de usuario de otros temas, hay básicamente dos enfoques principales:interfaz gráfica de usuario Actualización: Runnables vs Mensajes

  1. Uso java.lang.Runnable con cualquiera de estos métodos:

    Activity.runOnUiThread(Runnable) 
    View.post(Runnable) 
    View.postDelayed(Runnable, long) 
    Handler.post(Runnable) 
    
  2. uso android.os.Message:

    Handler.sendMessage(Message)/Handler.handleMessage(Message) 
    

También puede usar AsyncTask, pero mi pregunta está más centrada en el caso de uso de actualizar un componente muy simple. Vamos a ver cómo se llevaría a cabo utilizando los dos sistemas:

  1. Uso Runnables:

    TextViev tv = ...; 
    final String data = "hello"; 
    Runnable r = new Runnable() { 
    
        @Override 
        public void run(){ 
         tv.setText(data); 
        } 
    
    }; 
    //Now call Activity.runOnUiThread(r) or handler.post(r), ... 
    
  2. Uso de mensajes:

    Message m = handler.obtainMessage(UPDATE_TEXT_VIEW, "hello"); 
    handler.sendMessage(m); 
    
    //Now on handler implementation: 
        @Override 
        public void handleMessage(Message msg) { 
         if(msg.what == UPDATE_TEXT_VIEW){ 
          String s = (String) msg.obj; 
          tv.setText(data); 
         } ... //other IFs? 
        } 
    

en mi humilde opinión, los mensajes no son el camino a ir porque:

  • No es fácil de entender para los nuevos programadores no androides (los enganches del manejador a su rosca durante la construcción).
  • La carga útil del objeto debe ser Parcellable si el mensaje cruza los límites del proceso.
  • Los mensajes son reutilizados (propenso a errores si no se limpian adecuadamente?)
  • El controlador tiene una doble función (que envía mensajes, sino que también se ocupa de ellos)
  • atributos de mensajes son públicos, pero también ofrecen captador/definidor.

Por otro lado, Runnables sigue el conocido patrón de comandos, y son más amigables con los programadores y legibles.

¿Cuáles son las ventajas de usar Messages over Runnables? ¿Los mensajes están en segundo plano en la programación de Android moderna? ¿Hay algo que puedas hacer con los mensajes que no se pueden hacer con ejecutables?

Gracias de antemano.

Respuesta

4

Handler interfaz proporciona mucha más funcionalidad que runOnUiThread(), de acuerdo con docs:

Hay dos usos principales para un Handler:
(1) para programar mensajes y runnables a ser ejecutadas como un cierto punto en el future
(2) para poner en cola una acción que se realizará en un hilo diferente al suyo.

runOnUiThread solo hace un subconjunto de (2).es decir, "encolar una acción a realizar sobre hilo de interfaz de usuario"

Así OMI a menos que necesite esas características adicionales runOnUiThread es manera suficiente y preferida.

+0

Ok, tal vez la idea no está claramente expuesta en mi pregunta. No es Handler vs Runnables, sino Handler.sendMessage vs las alternativas Runnable. (Este grupo incluye también 'Handler.postDelayed' y' Handler.postAtTime', que cubren el n. ° 1) –

+0

. De hecho, explicaste bien la diferencia en tu publicación. No conozco ninguna otra diferencia que pueda agregar a eso. – Caner

12

Messages se pueden reutilizar, por lo que se generan menos objetos creados y menos GC. También terminas con menos clases y tipos anónimos.

Una gran ventaja es que una clase que envía un Message a un Handler no necesita saber nada sobre la implementación de ese Message. Eso puede ayudar en la encapsulación dependiendo de dónde se usa.

Por último tener en cuenta la diferencia en la limpieza entre

mHandler.obtainMessage(DO_STUFF, foo).sendToTarget(); 

vs

final Foo tempFoo = foo; 
mHandler.post(new Runnable(){ 
    @Override 
    public void run(){ 
     doStuff(tempFoo); 
    } 
}; 

Si tiene varios lugares donde se tendría que doStuff(), el primero es mucho más legible y tendrá menos duplicación de código.

+3

Runnables también se puede reutilizar, también es una interfaz y se puede crear una instancia de una manera más limpia que la que se muestra (que también es la que he publicado :)). –

+1

FWIW Creo que la clave aquí es que los mensajes no requieren que la clase construya/los envíe para saber nada sobre la forma en que se manejará el mensaje.Es una manera de exponer a un cliente que desea que le envíen cierta información, pero no qué se hará con ella. También es útil si desea poder intercambiar diferentes manejadores en tiempo de ejecución sin interferir con el código que genera los mensajes. Entonces, en el caso de la pregunta publicada, una actualización simple de UI como esta es bastante equivalente con un mensaje o un ejecutable. Pero ciertamente hay casos en que los mensajes ofrecen un beneficio adicional. –

+0

La razón principal por la cual los Mensajes serían útiles es porque el sistema operativo Android realmente los pone en cola, por eso en cualquier momento puede estar seguro de que los mensajes enviados más tarde solo se ejecutarán después de que se hayan ejecutado los mensajes anteriores enviados. – Bhargav

17

Yo diría que hay poca diferencia entre usar un Message contra un Runnable. En general, se reducirá a las preferencias personales. ¿Por qué? Al mirar el código fuente encontrará que publicar un Runnable utiliza el mismo mecanismo de mensajería exacta. Simplemente conecta el Runnable a un Message y lo envía.

4.4.2 Código Fuente

public final boolean post(Runnable r) { 
    return sendMessageDelayed(getPostMessage(r), 0); 
} 

private static Message getPostMessage(Runnable r) { 
    Message m = Message.obtain(); 
    m.callback = r; 
    return m; 
} 

Ref: Grep Code - Handler

+0

Hola, ¿puedes confirmar cuándo tenemos que implementar el método handleMessage? Me refiero a cuando necesitamos clase de Handler? porque podemos comunicarnos directamente al hilo de la interfaz de usuario principal al llamar a handler.post(); método. – UnKnown

+0

Sugerir publicación como nueva pregunta –

+0

Aquí he creado una nueva pregunta. https://stackoverflow.com/questions/47336380/when-we-need-to-override-handlers-handlemessage-method – UnKnown

1

prefiero Runnable-Message. Creo que el código que usa Runnable es mucho más claro que Message, porque el código de manejo de eventos está muy cerca del evento. Además, puede evitar la sobrecarga de definir constantes e intercambiar casos.

Y no creo que usar Runnable viole la encapsulación. Puede extraer el código en Runnable.run() en otro método en la clase externa, por ejemplo on...Event(), o incluso envolverlo en un objeto EventHandler. Ambas formas son mucho más claras que con Message, especialmente cuando necesita referencias de la tienda en Message, porque al usar Runnable se evita el downcasting msg.obj. Y el campo sin nombre msg.obj también es propenso a errores y a veces ineficiente de entender.

Y Runnable también se pueden reutilizar si se almacena como un campo.

Cuestiones relacionadas