I have a MapView with lots of overlay markers on it. It kind of works but tends to ANR when the markers are being added as there are a lot of them. So I've moved the code into an AsyncTask. Once moved, the code breaks, with the following exception bubbling up from the framework when the rendering is done. The error seems to be intermittent, but the more overlay items there are the more often it occurs.
What's causing the exception? How can I work around it?
11-24 12:40:44.316: ERROR/AndroidRuntime(6607): FATAL EXCEPTION: main
java.lang.ArrayIndexOutOfBoundsException: length=0; index=2
at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211)
at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240)
at com.company.myapp.MyOverlay.draw(TaxiOverlay.java:43)
at com.google.android.maps.Overlay.draw(Overlay.java:179)
at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42)
at com.google.android.maps.MapView.onDraw(MapView.java:530)
at android.view.View.draw(View.java:10982)
at android.view.ViewGroup.drawChild(ViewGroup.java:2899)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.ViewGroup.drawChild(ViewGroup.java:2897)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.ViewGroup.drawChild(ViewGroup.java:2897)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.ViewGroup.drawChild(ViewGroup.java:2897)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.ViewGroup.drawChild(ViewGroup.java:2897)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.ViewGroup.drawChild(ViewGroup.java:2897)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.ViewGroup.drawChild(ViewGroup.java:2897)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
at android.view.View.draw(View.java:10883)
at android.widget.FrameLayout.draw(FrameLayout.java:450)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2106)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2005)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1613)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2418)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
This is my class:
public class MarkersMapView extends MapView {
public void showMarkers() {
new showMarkersTask().execute();
}
public void clearMarkersFromMap() {
this.getOverlays().remove(markersOverlay);
Drawable drawable = this.getResources().getDrawable(R.drawable.ic_map_marker);
markersOverlay = new MarkerOverlay(drawable, this);
getOverlays().add(availableMarkersOverlay);
}
class showMarkersTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... voids) {
showTheMarkers();
return null;
}
protected void onProgressUpdate(Void v) {
invalidate();
}
protected void onPostExecute(Void v) {
}
private void showTheMarkers() {
Marker[] markers = Marker.getMarkerList();
if (markers == null || markers.length == 0) return;
clearMarkersFromMap();
for (User marker : markers) {
showMarker(marker.location.latitude, marker.location.longitude, marker.location.title, marker.location.subtitle);
publishProgress();
}
}
public void showMarker(float latitude, float longitude, String markerTitle, String markerSubtitle) {
GeoPoint point = new GeoPoint((int) (latitude * 1000000), (int) (longitude * 1000000));
OverlayItem marker = new OverlayItem(point, markerTitle, markerSubtitle);
markersOverlay.addOverlay(marker);
MarkerMapView.this.postInvalidate();
}
}
}
Shouldn't the access to the list of items be done on the ui thread? during the onPostProgress maybe?
and clearMarkersFromMap() during onPreExecute?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With