2010-10-01 9 views
1

Comment puis-je assurer le code est ou non exécuté sur le thread d'interface utilisateur dans un projet Android MapActivity? Je développe une application basée sur une carte Android, mais j'ai rencontré des problèmes de stabilité et ma recherche m'a amené à croire que je dois m'assurer que les mises à jour d'écran sont effectuées sur le thread de l'interface utilisateur. Mon application a des données venant d'un écouteur GPS (que je voudrais configurer comme un thread séparé) et un écouteur UDP (qui est déjà un fil séparé), et il a l'ensemble habituel du cycle de vie du logiciel Android méthodes, mais je dois être inexpérimenté ou quelque chose, parce que je ne sais pas où mettre le code qui met à jour les superpositions de cartefil Android MapActivity question

(a) sur le thread UI, (b) de manière récurrente. Je n'ai pas de préférence entre un processus d'interrogation ou un processus piloté par un événement (basé sur le minuteur, ou l'arrivée de données entrantes), donc les suggestions de l'un ou l'autre type seront acceptées avec reconnaissance.

Tout le monde a des idées ??

Merci, R.

Répondre

0

Lire la suite sur painless threading, en particulier les Activity.runOnUIThread

+0

Merci à tout le monde! ArtWorkAD: Merci pour la tête sur l'idée de fil séparé. J'ai commencé à me poser des questions à ce sujet peu de temps après avoir posté la question originale. – Rich

+0

Dang, je frappe à nouveau la touche retour !!! Je suis sûr qu'il existe de meilleures méthodes (juste en lisant les réponses sur cette page), mais je suis allé avec un gestionnaire et Runnable et utilisé postDelayed() pour appeler mon code de mise à jour de superposition toutes les 100 millisecondes. Ce n'est pas parfait, mais ça semble fonctionner. Je vais travailler sur les idées ici dès que possible. – Rich

+0

Malheureusement, je manque représentant suffisant pour vous donner un vote Up ... – Rich

0

Vous pouvez également consulter ce Handling Expensive Operations in UI Thread. Dans votre cas, vous pouvez effectuer les opérations suivantes:

MyActivity public class activité {

[ . . . ] 
// Need handler for callbacks to the UI thread 
final Handler mHandler = new Handler(); 

// Create runnable for posting 
final Runnable mUpdateResults = new Runnable() { 
    public void run() { 
     updateResultsInUi(); 
    } 
}; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //setup location listener 
    [ . . . ] 
    startNonUIThread(); 
} 

protected void startNonUIThread() { 

    // Fire off a thread to do some work that we shouldn't do directly in the UI thread 
    Thread t = new Thread() { 
     public void run() { 
      try{ 
      while(true){ 
       sleep(1000); 
       mHandler.post(mUpdateResults); 
      } 
      }catch(InterruptedException e){ 
      //blah blah 
      } 
     } 
    }; 
    t.start(); 
} 

private void updateResultsInUi() { 

    // Back in the UI thread -- update UI elements based on data from locationlistener 
    //get listener location 
    //use the location to update the map 
    [ . . . ] 
} 

}

0

Le service de localisation android est un module qui fonctionne en arrière-plan afin que vous n'avez pas besoin de séparer dans un autre fil.

Cependant, je ne vous conseille pas d'utiliser la classe de fil java ou interface Runnable du tout, utilisez la tâche async au lieu qui effectue toute la gestion des threads pour vous. Jetez un oeil sur le blog des développeurs Android, Painless Threading.

Pour mettre à jour votre thread d'interface utilisateur sur les mises à jour de l'emplacement que vous pouvez utiliser la mise à jour handlers. Chaque fois qu'il y a des données GPS disponibles, un message est transmis au gestionnaire de mise à jour dans votre thread ui principal.

E.g.

public void onLocationChanged(Location location) { 
    location = this.lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
    try { 
     this.mLongitude = location.getLongitude(); 
     this.mLatitude = location.getLatitude();  
     Message msg = Message.obtain(); 
     msg.what = UPDATE_LOCATION; 
     this.SystemService.myViewUpdateHandler.sendMessage(msg); 
    } catch (NullPointerException e) { 
     Log.i("Null pointer exception " + mLongitude + "," + mLatitude, null); 
    } 
} 

Et dans votre classe principale d'activité:

Handler myViewUpdateHandler = new Handler(){ 

     public void handleMessage(Message msg) { 
       switch (msg.what) { 
       case UPDATE_LOCATION:    
       //do something 
       } 
       super.handleMessage(msg); 
     } 
    }; 
+0

, Artwork, pour les heads-up à l'idée de thread séparé. J'ai commencé à me poser des questions à ce sujet peu de temps après avoir posté la question originale.ET je l'ai mis dans le mauvais bloc la 1ère fois. Gah !! – Rich

+0

de rien. Mais gardez à l'esprit que vous avez besoin d'un gestionnaire de mise à jour pour obtenir des données GPS. Je pense qu'il n'y a pas moyen de contourner. J'ai fait beaucoup de recherches sur ce sujet et j'ai toujours eu une exception nullpointer accédant aux champs lng et lat. donc vous avez besoin de quelque chose qui vous informe sur l'état du GPS, quand il y a des données GPS ou non. donc je l'ai fait en envoyant un message de l'instance de gps. –

+0

Je ne sais pas ce que vous entendez par "instance GPS" (je suis un ingénieur et pas vraiment un programmeur), mais j'ai configuré mon auditeur GPS comme une interface avec le rappel GpsReadDone (lat, long, time, dist), appelé par onLocationChanged(). La plupart des tâches effectuées par mon écouteur peuvent être exécutées directement, mais pour les mises à jour d'écran, j'utilise: runOnUiThread (Runnable doScreenUpdates). Utilisation postDelayed() DID travail, mais j'étais mécontent de la nature non synchronisée de l'implémentation. Je suis sûr qu'il serait encore plus cool d'implémenter une tâche asynchrone, mais cela semble inutile (et décourageant) maintenant. – Rich