Android 2.1 GoogleMaps ItemizedOverlay ConcurrentModificationException
Я не могу понять происхождение ConcurrentModificationException
, В моем activity
Я зову updateMapOverlay()
, Я тоже звоню updateMapOverlay()
внутри другой темы (TimerTask
), который вызывается на регулярной основе. Я беру соответствующие блокировки при вызове updateMapOverlay()
из обоих потоков. Эта проблема вызвана тем, что я вызываю updateMapOverlay
изнутри не-пользовательского потока (т. е. TimerTask
). Кто-нибудь еще сталкивался с подобной проблемой?
private void updateMapOverlay() {
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 ответа
Эта проблема вызвана, потому что я вызываю updateMapOverlay из потока не-пользовательского интерфейса
Да.
Я также вызываю updateMapOverlay() в другом потоке (TimerTask), который вызывается через регулярные промежутки времени.
Почему вы постоянно удаляете и добавляете оверлей? Просто обновите наложение и лишите законной силы. Смотрите здесь пример асинхронного обновления наложения.
Благодарю за ваш ответ.
Тем не менее, в вашем коде вы не делаете что-то подобное (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;
}
}
@Override public Void doInBackground(Void... unused) { SystemClock.sleep(5000); // simulated work sites=new SitesOverlay(); return(null);
}
@Override public void onPostExecute (Void unused) {. Map.getOverlays() добавить (сайтов); map.invalidate(); } }
Вообще говоря, вы должны быть в безопасности, пока вы изменяете только список поддержки / карту ItemizedOverlay в потоке пользовательского интерфейса.
Как отметил Марк, AsyncTask's:
@Override
protected void onPostExecute(Cursor cursor) {
// modify List/Map
populate();
mapView.invalidate();
}
всегда выполняется в потоке пользовательского интерфейса, поэтому изменения здесь безопасны.
У меня та же проблема. Чтобы ответить на ваш вопрос "почему вы постоянно удаляете и добавляете оверлей?", Я делаю это потому, что некоторые из моих оверлейных элементов могут больше не существовать или могут появиться новые, а существующие могут изменить местоположение в зависимости от что происходит в остальной части моего конкретного приложения. Кроме того, я не нашел способа изменить местоположение элемента OverlayItem без его расширения, чтобы я мог это сделать.
Кроме того, не вызовет ли изменение того, какие элементы в наложенном элементе наложение, также исключение одновременной модификации?