У меня есть карта с пользовательским наложением и связкой маркеров. Поскольку я делаю группировку маркеров при изменении масштаба, мне нужно очистить оверлей, перегруппировать элементы для нового масштабирования и снова наложить на карту. Я делаю это в фоновом потоке, чтобы все получилось гладким. Таким образом, вы нажимаете для увеличения, маркеры исчезают, индикатор занятости отображается в углу, и на карте появляются новые маркеры. все будет гладко, так как это должно, однако, я получаю неоправданное изменение исключения, когда вы дважды увеличиваете масштаб в строке или увеличиваете масштаб и уменьшаете масштаб сразу. Я много читал об этом, но ни один вариант не подходит для меня. Например, перенос переноса карты на onPostExecute, который находится в пользовательском интерфейсе, предотвращает это, но замораживает карту для того, чтобы метки времени были нарисованы, и она теряет свою гладкость. Я попытался сделать список меток в подробном оверлейном синхронизированном списке, но не помог. Как я могу это предотвратить?Android maps itemizedoverlay ConcurrentModificationException
Это то, что я называю по изменению масштабирования:
private void drawItems() {
final MyMapView mw = this.mapView;
//remove existing first
//mw.getOverlays().remove(stuffOverlay);
stuffOverlay.clearAll();
//mw.invalidate();
new AsyncTask<String, Integer, String>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
((ProgressBar)findViewById(R.id.mapProgressBar)).setVisibility(View.VISIBLE);
}
@Override
protected String doInBackground(String... params) {
//get items on map
HashMap<String, JSONArray> groupedItems = getItemsForZoom(mw.getZoomLevel());
if (groupedItems==null)
return "done";
//create a copy of it sometimes it was throwing concurentmodificationexception
HashMap<String, JSONArray> groupedItemsCopy = new HashMap<String, JSONArray> (groupedItems);
Iterator it = groupedItemsCopy.entrySet().iterator();
while (it.hasNext()) { //loop over markers
try {
//get item
HashMap.Entry<String, Object> pair = (HashMap.Entry)it.next();
JSONArray itemsInMarker = (JSONArray) pair.getValue();
JSONObject itemData = (JSONObject) itemsInMarker.get(0);
//get truncated coordinates
String coordsKey = pair.getKey();
String[] coordsSplitted = coordsKey.split("_");
//add first marker to map
GeoPoint gp = new GeoPoint((int)(Double.parseDouble(coordsSplitted[0])*1E6), (int)(Double.parseDouble(coordsSplitted[1])*1E6));
OverlayItem markerOverlay = new OverlayItem(gp, "marker", "snipper text");
Drawable markerPic = ServerCall.drawableFromUrl(((JSONObject)((JSONObject)itemData.get("picture")).get("1")).get("picture_full")+"_0.png");
//markerPic.setBounds(0, 0, markerPic.getIntrinsicWidth(), markerPic.getIntrinsicHeight());
markerPic.setBounds(-25, -25, 50, 50);
markerOverlay.setMarker(markerPic);
stuffOverlay.addOverlay(markerOverlay, itemData);
if (stuffOverlay.size() > 0) {
mapView.getOverlays().add(stuffOverlay);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return "done";
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
((ProgressBar)findViewById(R.id.mapProgressBar)).setVisibility(View.GONE);
mapView.invalidate();
}
}.execute();
}
Это мой детализированный оверлей:
private class StuffOverlay extends ItemizedOverlay {
private List<OverlayItem> mOverlays = Collections.synchronizedList(new ArrayList<OverlayItem>());
private ArrayList<JSONObject> mStuff = new ArrayList<JSONObject>();
public int currentItem;
Map mMap;
public StuffOverlay(Drawable defaultMarker, Map map) {
super(boundCenterBottom(defaultMarker));
mMap = map;
populate(); //keep here
}
public void addOverlay(OverlayItem overlay, JSONObject stuffData) {
synchronized (mOverlays) {
mOverlays.add(overlay);
}
mStuff.add(stuffData);
setLastFocusedIndex(-1); //keep here
populate();
}
public void clearAll() {
synchronized (mOverlays) {
mOverlays.clear();
}
setLastFocusedIndex(-1); //keep here
populate();
}
@Override
protected OverlayItem createItem(int i) {
synchronized (mOverlays) {
return mOverlays.get(i);
}
}
@Override
public int size() {
synchronized (mOverlays) {
return mOverlays.size();
}
}
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (!shadow) {
super.draw(canvas, mapView, false);
}
}
}
И это то, что я получаю, о (
05-30 20:45:35.485: W/dalvikvm(1139): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
05-30 20:45:35.485: E/AndroidRuntime(1139): Uncaught handler: thread main exiting due to uncaught exception
05-30 20:45:35.495: E/AndroidRuntime(1139): java.util.ConcurrentModificationException
05-30 20:45:35.495: E/AndroidRuntime(1139): at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64)
05-30 20:45:35.495: E/AndroidRuntime(1139): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:44)
05-30 20:45:35.495: E/AndroidRuntime(1139): at com.google.android.maps.MapView.onDraw(MapView.java:476)
05-30 20:45:35.495: E/AndroidRuntime(1139): at android.view.View.draw(View.java:6535)
05-30 20:45:35.495: E/AndroidRuntime(1139): at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
05-30 20:45:35.495: E/AndroidRuntime(1139): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
отличное место, вы абсолютно правы, и это действительно разрешило мою проблему. Благодарю. – Stan