2

Je craignais que trouver des informations de localisation (avec le géocodage inverse) sur le thread principal ne ralentisse mon interface utilisateur. Pour résoudre ce problème, j'ai mis l'info dans un AsyncTask (code ci-dessous) Maintenant, je veux ajouter des écouteurs de localisation, j'ai toutes sortes de problèmes. J'ai fait un peu de recherche et maintenant je me demande ... Est-il même nécessaire de mettre le code de localisation dans un AsyncTask? Peut-être que Android "naturellement" trouve des informations de localisation de manière asynchrone?Est-il nécessaire de trouver des emplacements dans un fil séparé?

public class LocationAsyncTask extends AsyncTask<Void, String, String> { 





     @Override protected void onPostExecute(String result) { 
      // TODO Auto-generated method stub 
      tvLocation.setText(result); 

      } 

     @Override 
     protected void onPreExecute() { 
      // TODO Auto-generated method stub 
      tvLocation.setText("Finding current location"); 

      } 


     @Override 
     protected String doInBackground(Void... params) { 
      // TODO Auto-generated method stub 
      LocationManager locationManager; 
      String context = Context.LOCATION_SERVICE; 
      locationManager = (LocationManager)getSystemService(context); 

      Criteria criteria = new Criteria(); 
      criteria.setAccuracy(Criteria.ACCURACY_FINE); 
      criteria.setAltitudeRequired(false); 
      criteria.setBearingRequired(false); 
      criteria.setCostAllowed(true); 
      criteria.setPowerRequirement(Criteria.POWER_LOW); 

      String provider = locationManager.getBestProvider(criteria, true); 
      Location location =locationManager.getLastKnownLocation(provider); 
      String strUpdateResult = updateWithANewLocation(location); 

     //locationManager.requestLocationUpdates(provider, 1000, 10, locationListener); 


      return strUpdateResult; 
      } 

     private String updateWithANewLocation(Location location) { 
      // TODO Auto-generated method stub 
      StringBuilder sbLocation = new StringBuilder(); 
      String strLocation = new String(); 
      TextView myLocationText; 

      String addressString = "No address found"; 
      String latLongString = ""; 

       //If there is a location 
       if (location!= null) { 

         double latitude = location.getLatitude(); 
         double longitude = location.getLongitude(); 
         double altitude = location.getAltitude(); 
         float accuracy = location.getAccuracy(); 
         float bearing = location.getBearing(); 
         long time = location.getTime(); 
         float speed = location.getSpeed(); 
         String prov = location.getProvider(); 
         strLocation = "Latitude: " + latitude + "\nLongitude: " + longitude + "\n" ; 
         publishProgress(strLocation); 

         Geocoder gc = new Geocoder(LateRunner.this, Locale.getDefault()); 
         try { 
          List<Address> addresses = gc.getFromLocation(latitude, longitude, 1); 

          //if location and then address is found 
          if (addresses.size() > 0) { 
           Address address = addresses.get(0); 

           for (int i=0; i <address.getMaxAddressLineIndex(); i++) { 
            sbLocation.append(address.getAddressLine(i)).append("\n"); 
           } 
           strLocation= sbLocation.toString(); 
           publishProgress(strLocation); 
          } 
          //if location but no address 
          else { 
           strLocation = "Latitude: " + latitude + "\nLongitude: " + longitude + "\n";  
           publishProgress(strLocation); 
          } //end try 

         } catch (IOException e) { 
          strLocation = "Latitude: " + latitude + "\nLongitude: " + longitude + "\n";  
          publishProgress(strLocation); 

         }//end catch 
        } 

       //If no location found 
       else { 
        strLocation = "Unable to find location. "; 
        publishProgress(strLocation); 
       } 
       return strLocation; 



     }// end updateWithANewLocation() 






     @Override protected void onProgressUpdate(String... result) { 
      // TODO Auto-generated method stub 
      tvLocation.setText(result[0]); 
      } 
     } 
+0

Pourriez-vous spécifier certaines de ces "toutes sortes de problèmes"? – MByD

+0

Je ne trouvais nulle part où placer l'emplacement locationListener (peu importe où je l'ai mis, par exemple, en le faisant un membre de l'AsyncTask, en déplaçant sur onCreate provoque le crash du périphérique). C'est pourquoi je voudrais abandonner l'AsyncTask tous ensemble si ce n'est pas nécessaire. – Mel

Répondre

3

J'ai fait une recherche rapide et je n'ai pas vu de références spécifiques à LocationManager exécutant async, mais mon hypothèse est que cela est planifié d'une manière qui n'a pas d'impact sur les performances de l'interface utilisateur. Par expérience, je n'ai eu aucun problème à trouver l'emplacement sur le thread principal et à le restituer à l'utilisateur. En fait, je calcule la distance pour environ 100 éléments dans une liste sans ralentissement notable sur l'interface utilisateur. Le dernier calcul est cependant où je dirais que vous devriez penser à AsyncTask, car il peut facilement influencer la performance. Cependant, veillez à la durée de mise à jour de vos tâches AsyncTask et de l'intervalle de mise à jour de l'emplacement LocationManager.

En fonction de la durée de chaque appel à updateWithANewLocation, vous pouvez envisager de le placer dans une tâche d'arrière-plan et laisser le LocationManager sur le thread principal.

Je suppose que vous avez un problème avec la gestion des événements sur le LocationManager. Les points suivants devraient donner un aperçu de cette partie de la question:

http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates%28java.lang.String,%20long,%20float,%20android.location.LocationListener%29

Le thread appelant doit être un fil Looper tels que le fil principal de l'activité appelant.

http://developer.android.com/reference/android/os/Looper.html

Fondamentalement, lorsque votre LocationAsyncTask fini d'exécution, son parti, de sorte que les rappels d'événements se produisent à un fil qui n'existe plus. Le Looper lancerait une boucle de message pour accepter ces événements LocationManager.

+0

Merci pour votre réponse. – Mel

-7

Core Location du SDK iOS fournit un objet CLLocationManager avec des méthodes d'instance appelées startUpdatingLocation et startMonitoringSignificantLocationChanges qui fonctionnent à la fois de manière asynchrone. Après avoir appelé l'un d'entre eux, vous n'avez qu'à implémenter le rappel locationManager:didUpdateToLocation:fromLocation pour gérer les mises à jour de l'emplacement. Je parie que Android fait quelque chose de similaire. Sinon, déposez un bug.

+0

Pourquoi la façon dont iOS fait les choses a-t-elle quelque chose à voir avec Android et le dépôt d'un bug? – blindstuff

+0

Parce qu'ils sont tous les deux des plates-formes très similaires et s'efforcent d'être les meilleurs. Si Apple fait quelque chose de bien avec iOS que Google ne fait pas, Google devrait emboîter le pas avec Android, et vice versa. – ma11hew28

+0

Le manque de fonctionnalité similaire à iOS n'est pas un bug, c'est une demande d'amélioration. – Dan

Questions connexes