Question

J'écris une application J2ME. L'un des éléments est quelque chose qui interroge périodiquement le contenu d'un répertoire et, s'il y a de nouvelles choses, les peint à l'écran. Pour ce faire, le formulaire d'interface utilisateur a lancé un thread d'interrogation avec un pointeur sur lui-même. Lorsque le thread d'interrogation trouve quelque chose, il rappelle au formulaire et appelle une méthode synchronisée pour mettre à jour son affichage. Cela semble bien fonctionner.

Ma question est la suivante. En C # / .NET, je sais que ce n’est pas bien d’avoir des threads non-UI mettant à jour l’UI, et la bonne façon de gérer cela est de le déléguer au thread UI.

E.g. les suivantes:

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

Existe-t-il un équivalent J2ME pour gérer ce processus? Qu'en est-il de Java? Ou bien Java / J2ME joue-t-il simplement mieux à cet égard? Si non, comment cela se fait-il?

[EDIT] Il semble que Swing prenne en compte ce que je demande via les méthodes SwingUtilities.invokeLater () et invokeAndWait (). Existe-t-il un cadre équivalent pour J2ME?

Était-ce utile?

La solution

En ce qui concerne Java, ce que vous décrivez ressemble à un SwingWorker (thread de travail) .

Lorsqu'un programme Swing doit exécuter une tâche de longue durée, il utilise généralement l'un des threads de travail, également appelé threads d'arrière-plan.

Un programme Swing inclut les types de threads suivants:

  • Les threads initiaux, les threads qui exécutent le code d'application initial.
  • Le thread de répartition des événements, où tout le code de gestion des événements est exécuté. La plupart du code qui interagit avec le framework Swing doit également être exécuté sur ce fil.
  • Les threads de travail, également appelés threads d'arrière-plan, exécutent des tâches d'arrière-plan fastidieuses.

Règle de thread unique :
Une fois qu'un composant Swing a été réalisé, tout le code pouvant affecter ou dépendre de l'état de ce composant doit être exécuté dans le thread de répartition des événements.

Lorsqu'il est utilisé dans un contexte J2EE, vous devez faire attention lorsque vous êtes référencer un SwingWorker à partir d'un EJB .

En ce qui concerne J2ME , cela dépend. si vous développez votre application en tant que MIDlet standard pouvant être exécuté sur tout périphérique compatible MIDP, ou par exemple en tant que RIMlet, application CLDC utilisant des API spécifiques à BlackBerry et, par conséquent, uniquement sur les terminaux BlackBerry.

Parce que, contrairement aux classes d'interface utilisateur de MIDP, les RIM sont similaires à Swing en ce sens que les opérations d'interface utilisateur se produisent sur le thread d'événement, qui n'est pas thread-safe comme dans MIDP. Pour exécuter le code sur le thread d'événement, une application doit obtenir un verrou sur l'objet événement ou utiliser invokeLater () ou invokeAndWait () & # 8211; travail supplémentaire pour le développeur, mais la sophistication a un prix.

Mais pour LCDUI , vous pouvez accéder à un formulaire à partir de plusieurs threads .

Autres conseils

Il existe de nombreux profils de Java ME. Si vous voulez dire MIDP, alors Display.runSerially est ce que vous voulez.

Pour AWT (Swing), vous utiliseriez EventQueue.invokeLater ( SwingUtilities.invokeLater n'est nécessaire que parce que Java 1.1 n'a pas le EventQueue . méthode - 1.2 est sur le point de célébrer son dixième anniversaire). Pour l'API DOM commune, utilisez DOMService.invokeLater .

Quelles que soient les revendications d'une API graphique sur la sécurité des threads, elles sont probablement erronées (certaines des revendications de Swing sont supprimées dans JDK7 car elles ne peuvent pas être implémentées). Dans tous les cas, il est peu probable que le code de l'application soit compatible avec les threads.

Pour les applications j2me, vous voulez probablement rester simple. L'essentiel est de toucher les composants de l'interface utilisateur uniquement dans le fil de l'événement. La méthode directe consiste à utiliser invokeLater ou invokeAndWait . En fonction de vos bibliothèques, vous n'aurez accès à rien d'autre. En général, si ceux-ci ne sont pas fournis sur votre plate-forme, cela signifie probablement qu'il n'y a pas de support de thread et n'est pas un problème. Par exemple, le BlackBerry le prend en charge .

Si vous développez sous SWT, cela s’effectue au moyen de la méthode asyncExec () de l’objet Display. Vous transmettez un objet implémentant Runnable pour que le thread d'interface utilisateur exécute les modifications effectuées dans un autre thread.

Ceci est un exemple emprunté à ici

.
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());
         }
      }
   }
}

Je peux attester que la boîte à outils de l'interface utilisateur MIDP est effectivement thread-safe, car j'ai de grands MIDlets avec une interface graphique complexe fonctionnant sur des millions de téléphones fabriqués par presque tous les fabricants, et je n'ai jamais vu de problème à cet égard.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top