2008-11-15 17 views
5

Estoy escribiendo una aplicación J2ME. Una de las piezas es algo que sondea el contenido de un directorio periódicamente y, si hay algo nuevo, las pinta en la pantalla. Hice esto al hacer que el formulario UI lanzara un hilo de sondeo con un puntero a sí mismo, y cuando el hilo de sondeo encuentra algo llama al formulario y llama a un método sincrónico para actualizar su visualización. Esto parece que funciona bien.Interactuando con hilos UI en Java/J2ME

La pregunta que tengo es esto. En C# /. NET sé que no es bueno tener subprocesos que no sean UI actualizando la UI, y la forma correcta de manejar esto es delegarlo hasta el subproceso UI.

E.g. lo siguiente:

public void DoSomeUIThing() 
{ 
    if (this.uiComponent.InvokeRequired) 
    { 
     this.uiComponent.Invoke(someDelegateThatCallsBackToThis); 
    } 
    else 
    { 
     this.uiComponent.Text = "This is the update I want to happen"; 
    } 
} 

¿Existe un equivalente J2ME para saber cómo manejar este proceso? ¿Qué hay de Java? ¿O Java/J2ME solo juega mejor con respecto a esto? Si no, ¿cómo se hace esto?

[EDITAR] Parece que Swing admite lo que estoy preguntando a través de los métodos SwingUtilities.invokeLater() y invokeAndWait(). ¿Hay un marco equivalente para J2ME?

+0

Acaba de completar mi respuesta con información específica de J2ME – VonC

+0

¡Gracias! Mi aplicación es LCDUI, así que supongo que no tengo que preocuparme por esto (al menos si creo en David Pierce). – Cory

Respuesta

5

En cuanto a Java, lo que está describiendo parece un SwingWorker (worker thread).

Cuando un programa Swing necesita ejecutar una tarea de larga ejecución, por lo general utiliza uno de los subprocesos de trabajo, también conocidos como subprocesos de fondo.

Un programa Swing incluye los siguientes tipos de hilos:

  • las discusiones iniciales, los hilos que ejecutan código de la aplicación inicial.
  • El hilo de envío de eventos, donde se ejecuta todo el código de manejo de eventos. La mayoría del código que interactúa con el marco Swing también debe ejecutarse en este hilo.
  • Subprocesos de trabajo, también conocidos como subprocesos de fondo, donde se ejecutan las tareas de fondo que consumen mucho tiempo.

Single-thread rule:
Una vez que un componente Swing se ha dado cuenta, todo el código que pueda afectar o depender del estado de ese componente debe ser ejecutado en el hilo de despacho de eventos.

Cuando se utiliza en un contexto J2EE, debe tener cuidado cuando es referencing a SwingWorker from an EJB.

En cuanto J2ME, que depende de si está desarrollando su aplicación como un MIDlet estándar que se pueden ejecutar en cualquier dispositivo MIDP habilitado, o por ejemplo como RIMlet, una aplicación basada en CLDC que utiliza BlackBerry-específica API y, por lo tanto, se ejecutará solo en dispositivos BlackBerry.

Porque a diferencia de las clases de IU de MIDP, los RIM son similares a Swing en el sentido de que las operaciones de IU ocurren en el hilo del evento, que no es seguro para subprocesos como en MIDP. Para ejecutar código en el hilo del evento, una aplicación debe obtener un bloqueo en el objeto del evento, o usar invokeLater() o invokeAndWait(): trabajo adicional para el desarrollador, pero la sofisticación viene con una etiqueta de precio.

Pero para LCDUI, puede access a form from multiple threads.

+0

Ver edición: el enlace "regla de una sola secuencia" describe cómo hacer esto para columpiarse. ¿Sabes algo sobre algo similar en J2ME? – Cory

1

Para las aplicaciones de j2me es probable que desee mantenerlo simple. Lo principal es tocar los componentes de UI solo en el hilo del evento. La forma directa de hacerlo es usar invokeLater or invokeAndWait. Dependiendo de sus bibliotecas, no tendrá acceso a nada más que eso. En general, si no se proporcionan en su plataforma, probablemente sea igual a que no haya soporte de subprocesos y no sea un problema. Por ejemplo the blackberry does support it.

1

Si desarrolla bajo SWT esto se logra por medio del método asyncExec() del objeto Mostrar. Pasa un objeto que implementa Runnable para que el subproceso UI ejecute los cambios realizados en otro subproceso.

Este es un ejemplo tomado de here

public void itemRemoved(final ModelEvent me) 
{ 
    final TableViewer tableViewer = this.viewer; 

    if (tableViewer != null) 
    { 
     display.asyncExec(new Runnable() 
     { 
     public void run() 
     { 
      tableViewer.remove(me.getItem()); 
     } 
     } 
    } 
} 
4

Hay muchos perfiles de Java ME. Si se refiere a MIDP, entonces Display.runSerially es lo que desea.

Para AWT (Swing) que usaría EventQueue.invokeLater (SwingUtilities.invokeLater sólo es necesario debido a Java 1.1 no tener el método EventQueue - 1.2 es a punto de celebrar su décimo cumpleaños). Para la API DOM común, use DOMService.invokeLater.

Independientemente de las afirmaciones que una API de GUI pueda hacer acerca de la seguridad de las hebras, probablemente sean erróneas (algunas de las afirmaciones de Swing se eliminan en JDK7 porque no son implementables). En cualquier caso, es poco probable que el código de la aplicación sea seguro para subprocesos.

1

Puedo dar fe de que el kit de herramientas MIDUI es seguro para subprocesos, ya que tengo MIDlets grandes con una GUI compleja que se ejecuta en millones de teléfonos fabricados por casi todos los fabricantes, y nunca he visto un problema en ese sentido.