在我的应用程序中,我有一个带有自定义MapOverlays的MapView。
我已经覆盖了onDraw方法,因此我可以对位于相同位置的叠加项进行聚类 - 并且效果很好。
我现在正在尝试添加一大堆标记,虽然我已经同步了方法和正确的对象但我得到了Concurrent Modification Error
。
我认为它与onDraw方法有关,每次需要时都会多次调用(在某些线程中可以读取) - 并且它必须在尝试的同时更新ArrayList迭代它。
我的问题是为什么?我确实同步了......它应该被锁定..
我的函数是从onDraw()调用的:
private synchronized ArrayList<OverlayItem> createOverlayItems(MapView mapView)
{
Projection projection = mapView.getProjection();
int minPixelDistance = app.getPixels(50); //distance allowed between 2 markers
synchronized (fullMapOverlays) {
OverlayItem me = getOverlayItem(ME);
fullMapOverlays.remove(me);
mapOverlays.clear();
mapOverlays.addAll(fullMapOverlays);
Iterator<OverlayItem> overlayIterator = fullMapOverlays.iterator();
while (overlayIterator.hasNext())
{
OverlayItem item = overlayIterator.next();
Point currentItemPoint = projection.toPixels(item.getPoint(), null);
if (!isPointInScreen(currentItemPoint))
continue;
else if (item.getTitle().equals(ME) && item.getSnippet().equals(ME))
continue;
else if (!mapOverlays.contains(item))
continue;
cluster.clear();
Iterator<OverlayItem> innerIterator = mapOverlays.iterator();
while (innerIterator.hasNext())
{
OverlayItem itemToCheck = innerIterator.next();
Point checkingItemPoint = projection.toPixels(itemToCheck.getPoint(), null);
if (!isPointInScreen(checkingItemPoint))
{
innerIterator.remove();
continue;
}
else if (itemToCheck.getTitle().equals(ME) && itemToCheck.getSnippet().equals(ME))
continue;
else if (itemToCheck.getTitle().equals(CLUSTER))
continue;
if (!item.equals(itemToCheck))
{
if (getPixelsDistance(currentItemPoint, checkingItemPoint) <= minPixelDistance)
{
cluster.add(itemToCheck);
innerIterator.remove();
}
}
}
if (cluster.size() > 0)
{
mapOverlays.remove(item);
cluster.add(item);
String itemsTitle = "";
for (int i=0; i<cluster.size(); i++)
{
if (i == 0)
itemsTitle += cluster.get(i).getTitle();
else
itemsTitle += "|" + cluster.get(i).getTitle();
}
OverlayItem clusterItem = new OverlayItem(cluster.get(0).getPoint(), CLUSTER, itemsTitle);
clusterItem.setMarker(boundCenterBottom(createClusterDrawable(cluster.size())));
mapOverlays.add(clusterItem);
}
}
fullMapOverlays.add(fullMapOverlays.size(), me);
mapOverlays.add(mapOverlays.size(), me);
}
return mapOverlays;
}
可爱的logcat:
01-25 00:27:47.070: W/System.err(4676): java.util.ConcurrentModificationException
01-25 00:27:47.070: W/System.err(4676): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
01-25 00:27:47.070: W/System.err(4676): at com.WhosAround.Activities.Map.MapOverlay.createOverlayItems(MapOverlay.java:169)
01-25 00:27:47.070: W/System.err(4676): at com.WhosAround.Activities.Map.MapOverlay.draw(MapOverlay.java:61)
01-25 00:27:47.070: W/System.err(4676): at com.google.android.maps.Overlay.draw(Overlay.java:179)
01-25 00:27:47.075: W/System.err(4676): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42)
01-25 00:27:47.075: W/System.err(4676): at com.google.android.maps.MapView.onDraw(MapView.java:530)
01-25 00:27:47.075: W/System.err(4676): at android.view.View.draw(View.java:6933)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.View.draw(View.java:6936)
01-25 00:27:47.075: W/System.err(4676): at android.widget.FrameLayout.draw(FrameLayout.java:357)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.View.draw(View.java:6936)
01-25 00:27:47.075: W/System.err(4676): at android.widget.FrameLayout.draw(FrameLayout.java:357)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.View.draw(View.java:6936)
01-25 00:27:47.075: W/System.err(4676): at android.widget.FrameLayout.draw(FrameLayout.java:357)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
01-25 00:27:47.075: W/System.err(4676): at android.view.View.draw(View.java:6936)
01-25 00:27:47.075: W/System.err(4676): at android.widget.FrameLayout.draw(FrameLayout.java:357)
01-25 00:27:47.075: W/System.err(4676): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1917)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewRoot.draw(ViewRoot.java:1530)
01-25 00:27:47.075: W/System.err(4676): at android.view.ViewRoot.performTraversals(ViewRoot.java:1266)
01-25 00:27:47.080: W/System.err(4676): at android.view.ViewRoot.handleMessage(ViewRoot.java:1868)
01-25 00:27:47.080: W/System.err(4676): at android.os.Handler.dispatchMessage(Handler.java:99)
01-25 00:27:47.080: W/System.err(4676): at android.os.Looper.loop(Looper.java:130)
01-25 00:27:47.080: W/System.err(4676): at android.app.ActivityThread.main(ActivityThread.java:3691)
01-25 00:27:47.080: W/System.err(4676): at java.lang.reflect.Method.invokeNative(Native Method)
01-25 00:27:47.080: W/System.err(4676): at java.lang.reflect.Method.invoke(Method.java:507)
01-25 00:27:47.080: W/System.err(4676): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
01-25 00:27:47.080: W/System.err(4676): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
01-25 00:27:47.080: W/System.err(4676): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
确定找到了,我从另一个Thread更新了MapActivity ....
您必须确保从UI线程添加OverlayItems。
答案 1 :(得分:0)
mapOverlays.remove(项目);看起来像是我的罪魁祸首。如果在迭代列表时直接删除项目,则会导致并发修改。
使用迭代器删除内容而不是直接删除。