Autore Topic: Lista non correttamente riempita  (Letto 613 volte)

Offline Elmvor

  • Utente normale
  • ***
  • Post: 166
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Ubuntu 14.04, Windows 8.1
Lista non correttamente riempita
« il: 12 Aprile 2014, 14:27:18 CEST »
0
Salve. Sono dinanzi ad un problema, forse banale ma mi sfugge qualcosa. Devo riempire una lista con oggetti LatLng presi dal parsing di un file GPX.
Quel che accade è che la lista sembra essere correttamente riempita all'interno dell'AsyncTask che effettua il parsing e poi risultare vuota nella classe chiamante!

Posto il codice:

Avvio il tutto dopo l'importazione del file GPX in questo modo:

Codice: [Seleziona]
//Creo un nuovo file per l'AsyncTask
                File file = new File(mCurFilePath);
                //Creo il Drawer a cui passo i dati necessari
                Drawer drawer = new GPXdrawer();
                drawer.setFile(file);
                drawer.setGoogleMap(mGoogleMap);
                drawer.setContext(MainActivity.this);
                drawer.templateMethodDraw();

Questa è la classe GPXdrawer

Codice: [Seleziona]
package com.loris.stefano.easyroutes.drawer;

import android.app.ProgressDialog;
import android.graphics.Color;
import android.location.Location;
import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Disegna il percorso a partire dal file GPX facendone il parsing
 *
 * Created by Loris on 10/04/2014.
 */
public class GPXdrawer extends AbstractDrawer {

    private static final String TAG_LOG = GPXdrawer.class.getName();

    /**
     * Effettua il disegno del file GPX importato.
     * 1) Controlla se è presente un vecchio tracciato. In
     * caso affermativo lo cancella
     * 2) Crea ed esegue l'AsyncTask che effettua il parsing
     * 3) Itera la lista di LatLng ed effettua il disegno
     */
    void draw() {

        deleteOldDrawing();

        if(!gpxLatLng.isEmpty()) {
            gpxLatLng.clear();
        }

        ParserAsyncTask parserAsyncTask = new ParserAsyncTask();
        parserAsyncTask.execute(file);

        Log.d(TAG_LOG, "Path size: " + gpxLatLng.size());

        for(int i = 0; i < gpxLatLng.size() - 1; i++) {

            LatLng src = gpxLatLng.get(i);
            LatLng dest = gpxLatLng.get(i + 1);

            PolylineOptions polylineOptions = new PolylineOptions()
                    .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude))
                    .width(4)
                    .color(Color.BLUE).geodesic(true);
            Polyline polyline = googleMap.addPolyline(polylineOptions);
            //Salvo le polylines nel caso voglia ridisegnare un altro tracciato
            gpxPolylines.add(polyline);
        }

        gpxLength();
    }

    /**
     * Cancella il vecchio percorso se presente
     */
    private void deleteOldDrawing() {

        googleMap.clear();

        if(!gpxPolylines.isEmpty()) {
            for(int i = 0; i < gpxPolylines.size(); i++) {
                gpxPolylines.get(i).remove();
            }
            //Resetto i valori di tempo e linghezza del tracciato
            mTrackDuration = 0;
            mTrackDistance = 0;
        }
    }

    /**
     * AsyncTask che si occupa di effettuare il parsing del GPX importato
     * per estrarne i dati latitudine e longitudine
     */
    private class ParserAsyncTask extends AsyncTask<File,Void,Void> {

        private ProgressDialog mDialog;

        protected void onPreExecute() {
            mDialog = ProgressDialog.show(context, "", "Caricamento...", true);
        }

        protected void onPostExecute(Void unused) {
            if(mDialog != null) {
                if(mDialog.isShowing()) {
                    mDialog.dismiss();
                }
            }
            Log.d(TAG_LOG, "Path size: " + gpxLatLng.size());
        }

        protected Void doInBackground(File... files) {

            try {
                //Si crea l’oggetto XmlPullParserFactory
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                //Abilitiamo il supporto ai namespace
                factory.setNamespaceAware(true);
                //Si crea l'XmlPullParser dal factory
                XmlPullParser parser = factory.newPullParser();
                //Si passa il file da parsare come input
                parser.setInput(new FileInputStream(files[0]),null);

                double lat = 0;
                double lon = 0;

                //Definisce il tipo di evento corrente
                int eventType = parser.getEventType();

                //Si cicla fin quando il documento non è finito (la fine è indicata dalla costante
                //END_DOCUMENT
                while(eventType != XmlPullParser.END_DOCUMENT) {
                    //Se è iniziato un nuovo TAG
                    if(eventType == XmlPullParser.START_TAG) {
                        //Prendiamo il nome del TAG
                        String tagName = parser.getName();
                        //Se il nome del tag è trkpt
                        if(tagName.compareTo("trkpt")==0) {
                            //Si estraggono latitudine e longitudine
                            lat = Double.parseDouble(parser.getAttributeValue(null, "lat"));
                            lon = Double.parseDouble(parser.getAttributeValue(null, "lon"));
                        }
                    }
                    //Se si è incontrato la fine del TAG
                    if(eventType == XmlPullParser.END_TAG) {
                        //Prendiamo il nome del TAG
                        String tagName = parser.getName();
                        //Se è il TAG trkpt
                        if(tagName.compareTo("trkpt")==0) {
                            //Si crea un nuovo oggetto LatLng da aggiungere alla
                            //lista mLatLng che verrà utilizzata per disegnare il tracciato
                            LatLng location = new LatLng(lat,lon);
                            //Log.d(TAG_LOG, "" + location);
                            gpxLatLng.add(location);
                        }
                    }
                    //Si prende il prossimo evento per continuare il ciclo
                    eventType = parser.next();
                }
            }
            catch (XmlPullParserException e) {
                e.printStackTrace();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    /**
     * Calcola la lunghezza del tracciato gpx
     */
    private void gpxLength() {
        for(int i=0; i < gpxLatLng.size()-1; i++) {
            LatLng firstLatLng = gpxLatLng.get(i);
            LatLng secondLatLng = gpxLatLng.get(i+1);
            mTrackDistance  += this.getDistance(firstLatLng,secondLatLng);
        }
    }

    /** Calcola la distanza tra due LatLng */
    private float getDistance(LatLng first, LatLng second) {
        float [] dist = new float[1];
        Location.distanceBetween(first.latitude, first.longitude, second.latitude, second.longitude, dist);
        return dist[0];
    }
}

I messaggi di Log stampano:

"Path size: 0"
"Path size: un numero" (quindi l'AsyncTask qualcosa riempie)

Come se prima venisse effettuato il disegno e poi avviato l'AsyncTask.

Cosa mi sfugge?


Ps: gpxLatLng è una lista creata ed inizializzata nella superclasse. Non viene disegnato niente sulla GoogleMap, ma nella MainActivity in un qualche modo il codice sa come spostare la visuale sul tracciato xD
« Ultima modifica: 12 Aprile 2014, 14:36:40 CEST da Elmvor »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Lista non correttamente riempita
« Risposta #1 il: 12 Aprile 2014, 15:44:54 CEST »
+1
Come se prima venisse effettuato il disegno e poi avviato l'AsyncTask.

Ma è esattamente cosa hai scritto nel codice: lanci un AsyncTask, e poi accedi immediatamente al risultato senza attendere che l'AsyncTask lo riempia.

Quello che non mi è chiaro è perchè lanci l'AsyncTask dentro draw(), a occhio dovresti avviare l'AsyncTask, e quando termina chiamare la draw().
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Elmvor

  • Utente normale
  • ***
  • Post: 166
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Ubuntu 14.04, Windows 8.1
Re:Lista non correttamente riempita
« Risposta #2 il: 12 Aprile 2014, 16:20:39 CEST »
0
Ah vero, dovrei chiamare il metodo draw() nell'onPostExecute! Allora dentro draw mi limito a chiamare l'AsyncTask, e dentro l'AsyncTask chiamerò un metodo che fa effettivamente il disegno.