java.util.ConcurrentModificationException On MapView - PullRequest
3 голосов
/ 17 февраля 2012

1001 * ребята *

У меня очень странная проблема из-за многих дней. Я пытаюсь часто обновлять оверлей. Так что иногда я получаю «java.util.ConcurrentModificationException», когда я касаюсь карты, или иногда, когда карта пытается обновить оверлей, но я не нахожу идеальную линию, которая появляется по этой ошибке.

02-17 14:56:01.621: W/dalvikvm(3653): threadid=1: thread exiting with uncaught exception (group=0x40015560)
02-17 14:56:01.631: E/AndroidRuntime(3653): FATAL EXCEPTION: main
02-17 14:56:01.631: E/AndroidRuntime(3653): java.util.ConcurrentModificationException
02-17 14:56:01.631: E/AndroidRuntime(3653):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:41)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at com.google.android.maps.MapView.onDraw(MapView.java:530)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.View.draw(View.java:6880)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.View.draw(View.java:6883)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.View.draw(View.java:6883)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.View.draw(View.java:6883)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewRoot.draw(ViewRoot.java:1522)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1258)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.os.Looper.loop(Looper.java:130)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at android.app.ActivityThread.main(ActivityThread.java:3683)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at java.lang.reflect.Method.invokeNative(Native Method)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at java.lang.reflect.Method.invoke(Method.java:507)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-17 14:56:01.631: E/AndroidRuntime(3653):     at dalvik.system.NativeStart.main(Native Method)

Я использую Наложение шаров

Я думаю, что это выдает ошибку на "mapview.getOverlay()", потому что это вызывает 4-5 раз в 1 секунду ..

Спасибо,

CapDroid

вот поток кода .. Код моей темы ....

Thread connection = new Thread(){
        public void run() {
            try {

                while (my condition)
                {
                    try 
                    {
                                        //This method should be call every seconds
                        updateMethod();
                    } 
                    catch (Exception e) 
                    {
                        e.printStackTrace();
                        break;
                    }
                } 
            } 
            catch (Exception e) 
            {

            }
        }
    };

Вот мой updateMethod (); в этом коде hashmapOverlay - это HashMap, как показано ниже

 public static Map<String,MyItemizedOverlay> hashmapOverlay;

 public void updateMethod()
{

                    if(hashmapOverlay.containsKey(id))
                        {
                            mapview.getOverlays().remove(hashmapOnlineFriendsOverlay.get(id));
                        }
                    MyItemizedOverlay mMyItemizedOverlay = new MyItemizedOverlay(drawable, mapview);
                        OverlayItem overlayItem = new OverlayItem(gp,title ,snippet);
                        mMyItemizedOverlay.addOverlay(overlayItem); 
                    hashmapOverlay.put(id, mMyItemizedOverlay);
                    addOverlayMethod(mActivity, mapView, mMyItemizedOverlay);   

}

Вот мой addOverlayMethod

addOverlayMethod(Activity mActivity, final MapView mapView, final Object mObject)
{
    mActivity.runOnUiThread(new Runnable(){

        @Override
        public void run()
        {

                try {
                    MyItemizedOverlay overlay = (MyItemizedOverlay) mObject;
                    mapView.getOverlays().add(overlay);
                } catch (Exception e)
                {}              

        }
    });
}

Ответы [ 5 ]

2 голосов
/ 17 февраля 2012

Чтобы избежать ConcurrentModificationException, просто скопируйте свою коллекцию в любом из следующих случаев:

  • до перебора коллекции
  • перед передачей в API

На первый взгляд, это может показаться излишним, но в дальнейшем это избавит вас от головной боли. Копирование просто, просто позвоните new ArrayList<YourClass>(existingList).

1 голос
/ 27 февраля 2012

да, вы можете обойти, шаг, как следует.

  1. Создать класс Pendingnotification (подробности модификации).
  2. Составить список Pendingnotification.
  3. когда получено какое-либо уведомление, не модифицируйте его напрямую, соберите все изменения и поместите стек (класс Pendingnotification), т.е.добавьте его в список ожидающих уведомлений.
  4. теперь один за другим измените объект и удалите тот же объект, когда его работа завершена.

следуйте тому же пути, пока Pendingnotification List не станет пустым.

Также обратите внимание, что любые изменения должны выполняться в UI Thread, а не в NonUI Thread

1 голос
/ 25 февраля 2012

Я не уверен насчет управления оверлеями, но, как я вижу, вы модифицируете свой HashMap с помощью HashMap.put в потоке без пользовательского интерфейса (в UpdateMethod), когда он, без сомнения, перебирается или используетсяв другом месте приложения - возможно, когда вы по-прежнему запрашиваете новые оверлеи, когда вы перемещаете карту.

Если вы прочитаете документы , это говорит о том, что это вызовет исключение ConcurrentModificationException.Вместо этого попробуйте использовать ConcurrentHashMap или реструктурируйте свой код, чтобы обновить хэш-карту в главном потоке, где он используется.

1 голос
/ 20 февраля 2012

Что ж, похоже, что в вашем updateMethod() вы все еще пытаетесь Update ваш пользовательский интерфейс из Non-UI потока на

mapview.getOverlays().remove(hashmapOnlineFriendsOverlay.get(id));

Итак, попробуйте выполнить эту часть вашего кода внутриRunOnUiThread и попробуйте.Надеюсь, это сработает.

UPDATE:

Кроме того, почему вы пытаетесь add и remove ваш Overlay все, вам не нужно это делать, просто попробуйте обновить Overlayи invalidate это.Have a look at this example.

1 голос
/ 17 февраля 2012

Я думаю, что вы используете Thread и его создание Concurrency Так что используйте Syncronized(MainActivity.this) в вашем методе выполнения .... И используйте вектор вместо списка, потому что вектор синхронизирован ... Это работает для меня ...1004 *

...