ItemizedOverlay中的ArrayIndexOutOfBoundsException

时间:2011-11-24 15:09:48

标签: android

我有一个包含大量叠加标记的MapView。它有点工作,但在添加标记时往往会出现ANR,因为有很多标记。所以我把代码移到了AsyncTask中。一旦移动,代码就会中断,在渲染完成后从框架中冒出以下异常。错误似乎是间歇性的,但是覆盖项越多,发生的次数越多。

导致例外的原因是什么?我该如何解决它?

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)

这是我的班级:

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

}
}

3 个答案:

答案 0 :(得分:5)

不应该在ui线程上访问项目列表吗?在onPostProgress期间可能吗?

在onPreExecute

期间

和clearMarkersFromMap()

答案 1 :(得分:0)

正如人们所说,不要尝试使用阵列,而不是使用其他地方。在这种情况下,不要试图在处理时显示标记(你可以这样做,但我建议在以后的日子里改进它),然后再将它们显示出结果:

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

        class showMarkersTask extends AsyncTask<Void, Void, Void> {

        protected Void doInBackground(Void... voids) {
            showTheMarkers();
            return null;
        }

        @Override
        protected void onPreExecute()
        {
            clearMarkersFromMap();
        }

        protected void onPostExecute(Void v) {
             getOverlays().add(markersOverlay);
        }

        private void showTheMarkers() {
            Marker[] markers = Marker.getMarkerList();
            if (markers == null || markers.length == 0) return;
            for (User marker : markers) {
                showMarker(marker.location.latitude, marker.location.longitude, marker.location.title, marker.location.subtitle);
            }
        }

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

        }
    }

答案 2 :(得分:-1)

如果任务中的某个阵列同时使用,则不应更新该任务中的数组。