2011-12-23 11 views
7

Ho avuto successo nell'aggiungere i pin della mappa alla sovrapposizione della mappa ma si carica lentamente e lo spostamento attorno alla mappa è lento. Sto pensando che è quando sta scaricando i pin della mappa dal server. I pin hanno dimensioni di circa 20-30 kb, ma a volte possono essere 25 pin da aggiungere. Ho già provato ad aggiungere i pin in background ma interromperà l'app. Cosa posso fare per aggiungere i pin in background senza influenzare le prestazioni?Utilizzo del task ASYNC per caricare i pin della mappa

Ricevo la posizione dalla mappa quando l'utente tocca la mappa ed esegue questo task ASYNC.

private class mapStations extends AsyncTask<Void, Void, JSONObject> { 

    @Override 
    protected JSONObject doInBackground(Void... arg0) { 

     JSONObject obj = null; 
     try { 
      obj = new JSONObject(API.nearByStations(pxLat, pxLng, 0)); 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return obj; 
    } 

    @Override 
    protected void onPostExecute(JSONObject details) { 
     String tag = "mapStations"; 
     JSONArray stations; 
     Drawable d = null; 
     try { 
      mapOverlays = mapView.getOverlays(); 
      mapOverlays.clear(); 
      stations = details.getJSONArray("stations"); 

      for (int j = 0; j < stations.length(); j++) { 
       JSONObject jsonObject = stations.getJSONObject(j); 
       Log.i(tag, "url: " + jsonObject.getString("logo")); 
       try { 

        Bitmap staticImage = BitmapFactory 
          .decodeStream((InputStream) new URL(jsonObject.getString("logo")) 
            .getContent()); 
        d = new BitmapDrawable(staticImage); 

       } catch (MalformedURLException e) { 
        Log.e(tag, e.toString()); 
        e.printStackTrace(); 
       } catch (IOException e) { 
        Log.e(tag, e.toString()); 
        e.printStackTrace(); 
       } 
       add(jsonObject.getDouble("lat"), 
         jsonObject.getDouble("lng"), d); 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

public void add(double lat, double lng, Drawable d) { 

    mapOverlays = mapView.getOverlays(); 
    if(d.equals(null)){ 
     Log.i(tag, "d was null"); 
     d = this.getResources().getDrawable(R.drawable.androidmarker); 
    } 

    itemizedOverlay = new MapsOverlay(d); 

    GeoPoint point = new GeoPoint((int) (lat * 1e6), (int) (lng * 1e6)); 
    OverlayItem overlayitem = new OverlayItem(point, "", ""); 

    itemizedOverlay.addOverlay(overlayitem); 
    mapOverlays.add(itemizedOverlay); 
} 

Questo è il logcat dall'aggiunta dei punti nel doinbackground. Non succede tutte le volte ma succede. Non riesco a riprodurmi neanche quando succede. A volte capita quando faccio lo zoom indietro, a volte capita quando mi muovo sulla mappa. Ho avuto una domanda simile su questo qui Android MapView JSON Array Adding Array of points ma ho finito per spostarlo sul post di esecuzione. Come ho detto prima, ci vuole un po 'per caricare i pin. Ora sono in perdita. Ci ho lavorato tutto il giorno.

[12-23 13:46:27.246: E/AndroidRuntime(1359): Uncaught handler: thread main exiting due to uncaught exception 
12-23 13:46:27.286: E/AndroidRuntime(1359): java.util.ConcurrentModificationException 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:41) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at com.google.android.maps.MapView.onDraw(MapView.java:476) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.View.draw(View.java:6535) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1531) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.View.draw(View.java:6538) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1531) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.View.draw(View.java:6538) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.widget.FrameLayout.draw(FrameLayout.java:352)][1] 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1531) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.View.draw(View.java:6538) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewRoot.draw(ViewRoot.java:1349) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1114) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1633) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.os.Handler.dispatchMessage(Handler.java:99) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.os.Looper.loop(Looper.java:123) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at android.app.ActivityThread.main(ActivityThread.java:4363) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at java.lang.reflect.Method.invoke(Method.java:521) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
12-23 13:46:27.286: E/AndroidRuntime(1359):  at dalvik.system.NativeStart.main(Native Method) 
+0

Definisci "interrompi l'app". Inoltre, Logcat. – MrZander

+0

Sarà forzato, ho apportato modifiche per il logcat e ho aggiunto commenti. –

risposta

2

Per impedire all'utente di modificare inavvertitamente l'elenco mentre è già in corso di modifica. Ho deciso di posizionare il dialogo nello onPreExecute() mentre i pin sono stati caricati. Ciò ha impedito all'utente di toccare la mappa mentre vengono aggiunti nuovi pin. Finché non riuscirò a trovare il tempo per trovare un'idea migliore su come impedire che ciò accada, questo dovrà essere fatto.

Cancella le sovrapposizioni dalla mappa prima di iniziare ad aggiungere nuovi pin, questo è completato durante onPreExecute(). Sul onPostExecute() lascio perdere la finestra di dialogo e invalidate() la mappa. Questo disegnerà i nuovi pin della mappa sulla mappa dopo averli aggiunti alla lista.

@Override 
    protected void onPreExecute() { 
     Log.i(tag, "AsyncTask Started"); 
     dialog.show(); 
     mapOverlays = mapView.getOverlays(); 
     mapOverlays.clear(); 
    } 

@Override 
    protected void onPostExecute(Void args) { 
     mapView.invalidate(); 
     dialog.dismiss(); 
     Log.i(tag, "AsyncTask Post"); 
    } 
1

Il ConcurrentModificationException di solito accade quando si sta cercando di modificare l'elenco, mentre l'iterazione di esso. Per superare l'eccezione, è possibile utilizzare un tipo di elenco speciale denominato CopyOnWriteArrayList. Permette in modo sicuro di aggiungere e rimuovere elementi da un elenco durante l'iterazione. Spero che questo ti aiuti.

+0

Mi dispiace ma sono ancora in perdita qui. Non riesco ancora a capire come posso realizzare il caricamento di questi pin in background. Questo è così casuale quando è su di me. Ottengo lo stesso errore in LogCat. L'ho ridotto alla funzione di aggiunta che causa il problema. Ho commentato la chiamata aggiunta alla funzione e l'errore si è interrotto. Quindi c'è qualcosa in questa funzione che mi sta causando questo problema. –

+0

@BrandonWilson, voglio dire, stai chiamando la funzione add() all'interno di un ciclo che scorre su un elenco e questo ti causa l'errore. Non è possibile modificare l'elenco durante l'iterazione, provare a trovare un'altra soluzione al problema. – Egor

+0

beh, sono un po 'bloccato a quello che sto provando. Quindi in sostanza sto cercando di modificare qualcosa che sto già modificando? Ho pensato che solo un AsyncTask poteva essere inserito in una volta. Sarebbe possibile aiutarmi qui. Capisco che tu mi abbia dato un indizio, ma questo non ha aiutato, mi dispiace. –

1

L'app si sta muovendo lentamente perché la funzione onPostExecute viene eseguita sul thread dell'interfaccia utente. La decodifica bitmap che stai facendo qui sta causando un rallentamento dell'interfaccia utente perché si tratta di una rete intensiva e lo stai facendo sul thread dell'interfaccia utente. Suggerirei di ottenere tutti i bitmap sul thread doInBackground e quindi di aggiungerli alla mappa sul metodo onPostExecute. L'unica cosa che dovresti fare sul thread dell'interfaccia utente è il metodo add.

+0

L'altro problema è che ottengo un 'ConcurrentModificationException' quando l'utente tocca la mappa mentre sta aggiornando l'elenco. L'unico modo per aggirare questo era usare una finestra di dialogo per impedire all'utente di toccare lo schermo. –

Problemi correlati