2011-11-24 16 views
6

Uso de la API com.google.android.maps, tengo una MapActivity que utiliza ItemizedOverlay colocar varios (hasta 1000) iconos en un MapView. Quiero actualizar (o quizás solo agregar a la lista de) los íconos cuando el LocationListener detecta que el dispositivo se ha movido a cierta distancia (actualmente 5 metros, pero eso es solo para probar).mapa refrescante ItemizedOverlay da ArrayIndexOutOfBoundsException

He añadido setLastFocusedIndex(-1) y populate(), pero mi ItemizedOverlay sigue estrelándose. Creo que está fallando cuando agrego más elementos a la lista, pero a veces parece fallar incluso si no muevo mi teléfono. Se bloquea en la primera actualización. No puedo decir desde LogCat exactamente qué desencadena el error.

Mi MapActivity está basada en varios tutoriales:

EDIT: ajustados código para hacer un batch update of items pero todavía falla

public class NearbyActivity extends MapActivity implements VenueCatalogListener { 
    private final String TAG = this.getClass().getSimpleName(); 

    List<Overlay> mapOverlays; 
    HelloItemizedOverlay itemizedOverlay; 

    private MapController mapController; 
    private MapView mapView; 
    private LocationManager locationManager; 

    private int latE6; 
    private int lonE6; 

    private Location current_location; 
    private VenuesFromServer venues_from_server; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     venues_from_server = new VenuesFromServer(this); 
     setupViews(); 
    } 

    private void setupViews() { 
     setContentView(R.layout.nearby_view); 


     RelativeLayout linearLayout = (RelativeLayout) findViewById(R.id.mapMainLayout); 

     mapView = new MapView(this, PreferencesManager.CLUBBERIA_MAPS_API_KEY); 
     initializeMap(); 

     linearLayout.addView(mapView); 
    } 

    private void initializeMap() { 
     mapView.setKeepScreenOn(true); 
     mapView.setClickable(true); 
     mapView.setBuiltInZoomControls(true); 
     mapController = mapView.getController(); 
     mapController.setZoom(mapView.getMaxZoomLevel()-5); // Zoom 1 is world view 

     locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new GeoUpdateHandler()); 

     mapOverlays = mapView.getOverlays(); 
     if(itemizedOverlay == null) { 
      Drawable drawable = this.getResources().getDrawable(R.drawable.icon); 
      itemizedOverlay = new HelloItemizedOverlay(drawable); 
      mapOverlays.add(itemizedOverlay); 
     } 
    } 

    @Override 
    protected boolean isRouteDisplayed() { 
     return false; 
    } 

    public class GeoUpdateHandler implements LocationListener { 
     @Override 
     public void onLocationChanged(Location location) { 
      if(current_location == null) { 
       current_location = location; 
      } 

      int lat = (int) (location.getLatitude() * 1E6); 
      int lng = (int) (location.getLongitude() * 1E6); 
      GeoPoint point = new GeoPoint(lat, lng); 
      if(current_location.distanceTo(location) > 5) { 
       // this kicks off an async task that will call back to venueListUpdated() below 
       venues_from_server.getVenueJSONFromServer(location.getLatitude(), location.getLongitude(), 19); 
      } 
      mapController.animateTo(point); // mapController.setCenter(point); 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
     } 
    } 

    @Override 
    public void venueListUpdated() { 

     // Base.B.arrayVenuesMap is an ArrayList<Venue> 
     for(int i=0;i<Base.B.arrayVenuesMap.size();i++) { 
      Venue _venue = Base.B.arrayVenuesMap.get(i); 
      latE6 = (int) (_venue.latitude*1e6); 
      lonE6 = (int) (_venue.longitude*1e6); 
      GeoPoint point = new GeoPoint(latE6, lonE6); 
      OverlayItem overlayitem = new OverlayItem(point, _venue.name, ""); 
      Drawable drawable = this.getResources().getDrawable(R.drawable.icon); 

      itemizedOverlay.addOverlay(overlayitem, drawable); 
     } 
     itemizedOverlay.batchPopulate(); 
    } 
} 

Mi ItemizedOverlay se parece a esto:

public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem> { 

    private ArrayList<OverlayItem> mOverlays = null; 

    public HelloItemizedOverlay(Drawable defaultMarker) { 
     super(boundCenterBottom(defaultMarker)); 
     mOverlays = new ArrayList<OverlayItem>(); 
     setLastFocusedIndex(-1); 
     populate(); 
    } 

    public void addOverlay(OverlayItem overlay, Drawable defaultMarker) { 
     if(!mOverlays.contains(overlay)) { 
      setLastFocusedIndex(-1); 
      overlay.setMarker(boundCenterBottom(defaultMarker)); 
      mOverlays.add(overlay); 
     } 
    } 

    public void batchPopulate() { 
     setLastFocusedIndex(-1); 
     populate(); 
    } 

    @Override 
    protected OverlayItem createItem(int i) { 
     return mOverlays.get(i); 
    } 

    @Override 
    public int size() { 
     return mOverlays.size(); 
    } 
} 

Logcat presenta las siguientes líneas:

11-24 18:28:02.245: D/AsyncJSONClient(18382): starting connect with this many pairs: 0; thread 17 
11-24 18:28:02.255: E/AndroidRuntime(18382): FATAL EXCEPTION: main 
11-24 18:28:02.255: E/AndroidRuntime(18382): java.lang.ArrayIndexOutOfBoundsException 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.Overlay.draw(Overlay.java:179) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.MapView.onDraw(MapView.java:530) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6918) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1947) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.draw(ViewRoot.java:1539) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.performTraversals(ViewRoot.java:1275) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.handleMessage(ViewRoot.java:1876) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.os.Handler.dispatchMessage(Handler.java:99) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.os.Looper.loop(Looper.java:123) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.app.ActivityThread.main(ActivityThread.java:3728) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at java.lang.reflect.Method.invokeNative(Native Method) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at java.lang.reflect.Method.invoke(Method.java:507) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at dalvik.system.NativeStart.main(Native Method) 
11-24 18:28:02.255: W/ActivityManager(308): Force finishing activity com.clubberia.android/.ClubberiaMain 

¿Cómo puedo ocasionalmente agregar elementos a ItemizedOverlay sin bloqueos?

Respuesta

3

ni saben que es un poco viejo, pero @cgwylie es casi justo ..

debe llamar populate() después de actualizar los valores de superposiciones ... y entonces usted puede llamar a la hmm postInvalidate()

0

Al cambiar los elementos de un ItemizedOverlay, es necesario llamar postInvalidate() en su MapView para hacerle saber que ha ajustado las superposiciones por lo que no va a tratar y sacar artículos que no están en la lista de nuevo.

En su venueListUpdated() puede probar agregar después de llamar al itemizedOverlay.addOverlay(overlayitem, drawable) para resolver su problema.

+0

. Acabo de probar tu sugerencia, pero no funcionó. ¡Gracias de cualquier manera! –

+0

Genial, lo siento, no funcionó, ya resolvió el problema en el pasado. – cgwyllie

Cuestiones relacionadas