Android 2.1 GoogleMaps ItemizedOverlay ConcurrentModificationException - PullRequest
1 голос
/ 20 мая 2010

Я не могу понять происхождение ConcurrentModificationException. По моему activity я звоню updateMapOverlay(). Я также вызываю updateMapOverlay() внутри другого потока (TimerTask), который вызывается через регулярные промежутки времени. Я беру соответствующие блокировки при вызове updateMapOverlay() из обоих потоков. Эта проблема вызвана тем, что я вызываю updateMapOverlay из потока, не являющегося пользовательским интерфейсом (то есть TimerTask). Кто-нибудь еще сталкивался с подобной проблемой?

private void updateMapOverlay() {</p> <pre><code> this.itemizedOverlay.refreshItems(createOverlayItemsList()); List<Overlay> overlays = mapView.getOverlays(); overlays.clear(); overlays.add(cotItemizedOverlay); this.mapview.invalidate(); }

Спасибо.

Исключение :

W/dalvikvm(10641): threadid=3: thread exiting with uncaught exception (group=0x4001b180)
E/AndroidRuntime(10641): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime(10641): java.util.ConcurrentModificationException
E/AndroidRuntime(10641):    at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64)
E/AndroidRuntime(10641):    at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:41)
E/AndroidRuntime(10641):    at com.google.android.maps.MapView.onDraw(MapView.java:494)
E/AndroidRuntime(10641):    at android.view.View.draw(View.java:6535)
E/AndroidRuntime(10641):    at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
E/AndroidRuntime(10641):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
E/AndroidRuntime(10641):    at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
E/AndroidRuntime(10641):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
E/AndroidRuntime(10641):    at android.view.View.draw(View.java:6538)
E/AndroidRuntime(10641):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime(10641):    at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
E/AndroidRuntime(10641):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
E/AndroidRuntime(10641):    at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
E/AndroidRuntime(10641):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
E/AndroidRuntime(10641):    at android.view.View.draw(View.java:6538)
E/AndroidRuntime(10641):    at android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime(10641):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830)
E/AndroidRuntime(10641):    at android.view.ViewRoot.draw(ViewRoot.java:1349)
E/AndroidRuntime(10641):    at android.view.ViewRoot.performTraversals(ViewRoot.java:1114)
E/AndroidRuntime(10641):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
E/AndroidRuntime(10641):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(10641):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(10641):    at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime(10641):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(10641):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(10641):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime(10641):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime(10641):    at dalvik.system.NativeStart.main(Native Method)
I/Process (   95): Sending signal. PID: 10641 SIG: 3

Ответы [ 4 ]

5 голосов
/ 20 мая 2010

Эта проблема вызвана тем, что Я вызываю updateMapOverlay из внутри не-пользовательского потока

Да.

Я также вызываю updateMapOverlay () внутри другой темы (TimerTask) это вызывается через регулярные промежутки времени.

Почему вы постоянно удаляете и добавляете оверлей? Просто обновите оверлей и лишите законной силы. См. здесь для примера обновления наложения асинхронно.

1 голос
/ 14 декабря 2010

Вообще говоря, вы должны быть в безопасности, если только изменяете список поддержки / карту ItemizedOverlay в потоке пользовательского интерфейса.

Как отметил Марк, AsyncTask's:

@Override
protected void onPostExecute(Cursor cursor) {

    // modify List/Map

    populate();
    mapView.invalidate();
}

всегда выполняется в потоке пользовательского интерфейса, поэтому изменения здесь безопасны.

1 голос
/ 20 мая 2010

Спасибо за ваш ответ.

Однако в вашем коде вы не делаете что-то подобное (map.getOverlays().remove(sites); и map.getOverlays().add(sites);)?

class OverlayTask extends AsyncTask { @Override public void onPreExecute() { if (sites!=null) { map.getOverlays().remove(sites); map.invalidate(); sites=null; } }</p> <pre><code> @Override public Void doInBackground(Void... unused) { SystemClock.sleep(5000); // simulated work sites=new SitesOverlay(); return(null);

}

@Override
public void onPostExecute(Void unused) {
  map.getOverlays().add(sites);
  map.invalidate();
 }
}
</code>
0 голосов
/ 12 ноября 2010

У меня такая же проблема. Чтобы ответить на ваш вопрос о том, «почему вы постоянно удаляете и добавляете оверлей?», Я делаю это, потому что некоторые из моих оверлейных элементов могут больше не существовать или могут появиться новые, а существующие могут изменить местоположение в зависимости от что происходит в остальной части моего конкретного приложения. Кроме того, я не нашел способа изменить местоположение элемента OverlayItem без его расширения, чтобы я мог это сделать.

Кроме того, не изменится ли то, что элементы в наложенном элементе, также приведет к исключению одновременной модификации?

...