我有一个包含大量叠加标记的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();
}
}
}
答案 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)
如果任务中的某个阵列同时使用,则不应更新该任务中的数组。