Updated ItemizedOverlay map gives ArrayIndexOutOfBoundsException

Using the com.google.android.maps API, I have a MapActivity that uses ItemizedOverlay to place multiple (up to 1000) icons on a MapView . I want to refresh (or maybe just add to the list) the icons when the LocationListener detects that the device has moved a certain distance (currently 5 meters, but this is just for testing).

I added setLastFocusedIndex(-1) and populate() , but my ItemizedOverlay is still crashing. I think this is crashing when I add more items to the list, but sometimes it seems to crash even if I don't move my phone. It crashes on the first update. I cannot tell from LogCat what exactly causes the error.

My MapActivity is based on various tutorials:

EDIT : modified code for batch updating items but it still crashes

 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(); } } 

My ItemizedOverlay looks like this:

 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 has the following lines:

 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 

How can I sometimes add items to ItemizedOverlay without crashing?

+6
source share
2 answers

ni knows him a little old, but @cgwylie is almost right.

you must call populate() after updating the overlay values ​​... and then you can call postInvalidate()

+3
source

When you change the elements in ItemizedOverlay , you need to call postInvalidate() on the MapView so that it knows that you have adjusted the overlays so that it does not try and draw elements that are not in again.

In venueListUpdated() you can try adding mapView.postInvalidate() after calling itemizedOverlay.addOverlay(overlayitem, drawable) to solve your problem.

0
source

Source: https://habr.com/ru/post/902292/


All Articles