1

我一直在尝试修复导致间歇性 ConcurrentModificationException 的错误。发生的事情是,我有大量的地理点与 ItemizedOverlay 一起显示。然而,当地图移动时,我试图清除所有当前的覆盖项目(地理点)并将它们替换为适合新视图窗口的新点。

因此,我有一个回调函数,可以清除旧的叠加层并用新的叠加层替换它们。我认为我的错误源于多个线程试图同时执行此操作。相关部分如下。我对覆盖和此类工作如何在低级别上的理解非常有限,所以我想知道是否有人可以确认(或反驳)这可能会导致问题。

//first clear out the old overlays
List<Overlay> mapOverlays = mapView.getOverlays();
mapOverlays.clear();

//create the new overlays, each initialized with appropriate Drawables
MenuOverlay lowOverlay = new MenuOverlay(this, lowRisk);//(all valid Drawables)
MenuOverlay medOverlay = new MenuOverlay(this, medRisk);
MenuOverlay highOverlay = new MenuOverlay(this, highRisk);

//populate the overlays

//add the new overlays into the list of overlays
mapOverlays.add(lowOverlay);
mapOverlays.add(medOverlay);
mapOverlays.add(highOverlay);

//make the map refresh; this operation has to be pushed to another thread
Runnable runnable = new Runnable() {
    public void run() {
        mapView.invalidate();
    }
};
runOnUiThread(runnable);

我尝试制作此方法synchronized,但错误仍然发生。这可能是由于在前一个可运行对象终止之前将新的可运行对象推送到 UI 线程而引起的吗?我已经看到提到填充是比无效更好的方法,尽管我不完全确定它们有何不同。任何想法如何解决这个问题?

4

1 回答 1

1

修改覆盖集应始终在 UI 线程上完成。返回的由 拥有List,它可以随时决定查看或操作列表。getOverlays()MapView

由于您正在处理大量地理点,因此您的后台线程可能正在清除(或添加)覆盖,同时在MapViewUI 线程上对其进行迭代。这将触发 aConcurrentModificationException因为迭代器在其底层覆盖集更改时无效。有时更改不会立即对 UI 线程可见,因此崩溃是间歇性的。

设置叠加层通常是此类工作流程中较慢的部分。为避免并发修改,您可以在后台线程中设置叠加层,clear()然后add()Runnable. (另一种选择是使用AsyncTask.)

例如:

// Slow setup steps
final MenuOverlay lowOverlay = new MenuOverlay(this, lowRisk);
final MenuOverlay medOverlay = new MenuOverlay(this, medRisk);
final MenuOverlay highOverlay = new MenuOverlay(this, highRisk);

Runnable runnable = new Runnable() {
    public void run() {
        // Anything that touches UI widgets (map, overlay set, views, etc.)
        List<Overlay> mapOverlays = mapView.getOverlays();
        mapOverlays.clear();

        mapOverlays.add(lowOverlay);
        mapOverlays.add(medOverlay);
        mapOverlays.add(highOverlay);

        mapView.invalidate();
    }
};

runOnUiThread(runnable);
于 2013-01-24T01:00:47.317 回答