3

fellas

I am facing very strange issue from many days. I am trying to update overlay frequently. So sometime I am getting "java.util.ConcurrentModificationException" when I touch on map or sometime getting when map trying to update overlay But I am not finding perfect line which on this error is coming.

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)

I am using Balloon Overlay

I think it is throwing error on "mapview.getOverlay()" because it is calling 4-5 times in 1 seconds..

Thanks,

CapDroid

here is code flow.. My Thread code....

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) 
            {

            }
        }
    };

Here is My updateMethod(); in this code hashmapOverlay is HashMap like as below

 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);   

}

Here is my 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)
                {}              

        }
    });
}
Niranj Patel
  • 32,980
  • 10
  • 97
  • 133

5 Answers5

2

In order to avoid ConcurrentModificationException simply copy your collection in any of the following cases:

  • before iterating over a collection
  • before passing it into an API

At first glance, this might seem like overkill but it will save you a lot of headache later on. Copying is simple, just call new ArrayList<YourClass>(existingList).

Matt
  • 17,290
  • 7
  • 57
  • 71
  • hi @Matt I also did it but I am not sure about it will 100% solved my issue or not? – Niranj Patel Feb 17 '12 at 10:32
  • If you no longer get any `ConcurrentModifictionException`, well, yes :) – Matt Feb 17 '12 at 10:33
  • I think it is throwing error on "mapview.getOverlay()" because it is calling 4-5 times in 1 seconds.. is it possible? – Niranj Patel Feb 17 '12 at 10:38
  • 1
    In general this error happens if you iterate over a collection and at the same time the collection changes. So, theoretically yes, but I don't know anything about the concrete implementation details of map overlays. I think the best solution would be, if you could provide a sample project which reproduces the error so that we can debug it. – Matt Feb 17 '12 at 11:00
  • Hello I edited my question with code can you help me now? @Matt – Niranj Patel Feb 21 '12 at 06:13
1

I think You use Thread and its create Concurrency So use Syncronized(MainActivity.this) in Your Run Method....And Use Vector Instead of List Because Vector is Syncronized...Its Works for me...

Samir Mangroliya
  • 39,918
  • 16
  • 117
  • 134
1

Well, it seems that in your updateMethod() you are still trying to Update your UI from a Non-UI thread by

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

So, try to execute this part of your code inside the RunOnUiThread and try. Hope this would work.

UPDATE:

Also, why you are trying to add and remove your Overlay everything, you don't need to do that just try to update your Overlay and invalidate it. Have a look at this example.

Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
  • I also tried it when I put it then my application is hang.. bcz that method is calling manytimes at time – Niranj Patel Feb 20 '12 at 06:13
  • one more thing this error is coming when i touch on map or any overlay otherwise it is working fine – Niranj Patel Feb 20 '12 at 06:14
  • Hello @Lalit Poptani I put RunOnUiThread only for remove line but still getting error..and already seen that example but i also want popup when user touch on overlay so .......etc – Niranj Patel Feb 20 '12 at 06:35
1

I'm not sure about the overlay management, but the way I see it, you're modifying your HashMap with HashMap.put on a non-UI thread (in UpdateMethod), when it's no doubt being iterated over or used elsewhere in the app - probably when still requesting new Overlays as you move your map around.

If you read the docs, it says this will cause a ConcurrentModificationException. Instead, try using a ConcurrentHashMap, or restructure your code to update the hashmap on the main thread where it is being used.

Mo Kargas
  • 1,000
  • 7
  • 24
1

ya, you can do a work around, step as follow.

  1. Make a Pendingnotification class(modication detail).
  2. Make a list of the Pendingnotification.
  3. when any notification receive dnt modify it directly, Collect all the modification and put stack(Pendingnotification class) ie. add it in Pendingnotification list.
  4. now one by one modify the object and remove the same object when its work done.

same way follow untill Pendingnotification List become empty.

And also note that any modification must be perform in UI Thread not in NonUI Thread

Mohammed Azharuddin Shaikh
  • 41,633
  • 14
  • 96
  • 115