2017-08-14 3 views
0

J'ai une MapsActivity pour montrer Google Maps sur mon application. J'ai un fichier texte où j'ai des noms de rues, des codes postaux et des noms de villes. J'ai lu ce fichier texte en utilisant BufferedReader. Il y a près de 100 rues dans mon fichier texte. Ainsi, j'ajoute par programmation près de 100 marqueurs dans Google Map. Cela prend du temps, et cela dépend de la connexion Internet.AsyncTask fonctionne sporadiquement Android

Par conséquent, j'ai décidé d'utiliser AsyncTask. Depuis que je sais, que les choses de l'interface utilisateur ne peuvent pas être faites dans doInBackground j'ai mis ma méthode readfile() (qui ajoute ces 100 marqueurs) dans doInBackground comme un thread exécutable. Et je ne veux pas que l'utilisateur voie un écran vide, donc j'ai ajouté un ProgressBar.

Et voici le problème: Le Progressbar ne fonctionne pas toujours, il est pas toujours vu, il est sporadiquement vu, qui me a conduit à de l'hypothèse que quelque chose ne va pas avec mon Asycntask. Peut-être que la façon dont j'appelle mon AsyncTask est mauvaise. S'il vous plaît jeter un oeil à mon code.

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback { 
private GoogleMap mMap; 
String city, adress, zip; 
LatLngBounds.Builder builder = new LatLngBounds.Builder(); 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 


    setContentView(R.layout.activity_maps); 

    // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
      .findFragmentById(map); 
    mapFragment.getMapAsync(this); 


} 


@Override 
public void onMapReady(GoogleMap googleMap) { 
    mMap = googleMap; 

    new Test().execute(null,null,null); //calling AsyncTask 

} 


public void readFile() { 

    Geocoder coder = new Geocoder(MapsActivity.this, Locale.getDefault()); 
    List<Address> address; 
    LatLng p2; 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("liste.txt"))); 
     String line; 

     while ((line = reader.readLine()) != null) { 

      String splittedLine[] = line.split(","); 
      int numberofElements = 2; 
      String[] onlyAdressandZip = Arrays.copyOf(splittedLine, numberofElements); 

      if (address.size() !=0) { 

       Address location = address.get(0); 
       location.getLatitude(); 
       location.getLongitude(); 

       p2 = new LatLng(location.getLatitude(), location.getLongitude()); 

       mMap.addMarker(new MarkerOptions().position(p2).title("Location " + onlyAdressandZip[0]+"," + onlyAdressandZip[1])); 
       builder.include(p2); 

       LatLngBounds bounds = builder.build(); 
       mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20)); 

      } 

       } 

    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 

} 


public class Test extends AsyncTask<Void, Void, Void>{ 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // what to do before background task 
     dialog = new ProgressDialog(MapsActivity.this); 
     dialog.setTitle("Loading..."); 
     dialog.setMessage("Please wait."); 
     dialog.setIndeterminate(true); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 



    @Override 
    protected Void doInBackground(Void... params) { 
     runOnUiThread(new Runnable() { 
      public void run() { 

       readFile(); 

      } 
     }); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void foo) { 
    super.onPostExecute(foo); 
    dialog.cancel(); 

    } 
} 
} 
+1

vous essayez d'exécuter un uithread sur un fil de travailleurs. vous devriez lire le fichier en arrière-plan et utiliser 'onProgressUpdate()' (il s'exécute dans l'utilitaire uithread en appelant 'publishProgress()') pour mettre à jour la barre de progression. Lire plus sur [AsyncTask ici] (https://developer.android.com/reference/android/os/AsyncTask.html) .. –

+0

@MatiasOlocco pouvez-vous me montrer un exemple de code s'il vous plaît? – ckbln

+1

Dans la documentation il y a un exemple de travail parfait, s'il vous plaît lisez-le. –

Répondre

1

Alors, comme je l'ai dit dans les commentaires, dans cet exemple, au fond, je re-écrit votre tâche async pour exécuter la lecture du fichier en arrière-plan, et la mise à jour des progrès de la carte dans le uithread. Le code est loin d'être définitif, mais vous devriez le tester et l'améliorer. Parce qu'une asyncTask vous donne les outils pour mettre à jour uithreads, vous ne devriez jamais utiliser runOnUiThread() là-dedans.

Le doc dit:

AsyncTask permet une utilisation correcte et facile du thread d'interface utilisateur. Cette classe vous permet d'effectuer des opérations d'arrière-plan et de publier des résultats sur le thread d'interface utilisateur sans avoir à manipuler des threads et/ou des gestionnaires.

L'exemple:

public class Test extends AsyncTask<Void, WrapperObject, Void> { 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // what to do before background task 
     dialog = new ProgressDialog(MapsActivity.this); 
     dialog.setTitle("Loading..."); 
     dialog.setMessage("Please wait."); 
     dialog.setIndeterminate(true); 
     dialog.setCancelable(false); 
     dialog.show(); 
    } 


    @Override 
    protected Void doInBackground(Void... params) { 

     Geocoder coder = new Geocoder(MapsActivity.this, Locale.getDefault()); 
     List<Address> address; 
     LatLng p2; 

     try { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("liste.txt"))); 
      String line; 

      while ((line = reader.readLine()) != null) { 

       String splittedLine[] = line.split(","); 
       int numberofElements = 2; 
       String[] onlyAdressandZip = Arrays.copyOf(splittedLine, numberofElements); 

       if (address.size() != 0) { 

        Address location = address.get(0); 
        location.getLatitude(); 
        location.getLongitude(); 

        p2 = new LatLng(location.getLatitude(), location.getLongitude()); 
        builder.include(p2); 

        WrapperObject wrapperObject = new WrapperObject(); 
        wrapperObject.bounds = builder.build(); 
        wrapperObject.latlng = p2; 
        wrapperObject.onlyAdressandZip = onlyAdressandZip; 
        publishProgress(wrapperObject); 
       } 

      } 

     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
     return null; 
    } 

    protected void onProgressUpdate(WrapperObject... wrapperObjects) { 
     WrapperObject wrapperObject = wrapperObjects[0]; 
     mMap.addMarker(new MarkerOptions().position(wrapperObject.latlng).title("Location " + wrapperObject.onlyAdressandZip[0]+"," + wrapperObject.onlyAdressandZip[1])); 
     mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(wrapperObject.bounds, 20)); 
    } 

    @Override 
    protected void onPostExecute(Void foo) { 
     super.onPostExecute(foo); 
     dialog.cancel(); 
    } 
} 
//this is a wrapper to update the progress, you should make this better.  
public static class WrapperObject { 
    public LatLng latlng; 
    public LatLngBounds bounds; 
    public String[] onlyAdressandZip; 
} 
+0

Ohshit, ça a vraiment marché. J'apprécie vraiment votre aide :) – ckbln

+0

heureux d'aider! Assurez-vous de lire et de comprendre le document. Il est important de savoir comment utiliser Asynctasks dans le futur. –