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

        }
    });
}
4
  • Can I see where you are trying to modify/update your Overlay? Commented Feb 17, 2012 at 10:02
  • there are many class and overlay packages so i can't show all here.. thanks brother Commented Feb 17, 2012 at 10:07
  • Make sure that you are trying to refresh or update your Overlay from UI thread itself and not from Non-UI thread. Commented Feb 17, 2012 at 10:08
  • @LalitPoptani Hello I edited my question with code can you help me now? Commented Feb 20, 2012 at 6:01

5 Answers 5

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

Sign up to request clarification or add additional context in comments.

5 Comments

hi @Matt I also did it but I am not sure about it will 100% solved my issue or not?
If you no longer get any ConcurrentModifictionException, well, yes :)
I think it is throwing error on "mapview.getOverlay()" because it is calling 4-5 times in 1 seconds.. is it possible?
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.
Hello I edited my question with code can you help me now? @Matt
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...

9 Comments

there are many overlay and all are updating from service class I also put in runOnUiThread..
@CapDroid I have same issue and its occure some times so i do R&D and get this final solution....
and one more thing sometime it will be update 4-5 time in 1 seconds
@Samir Vector is deprecated.
|
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.

3 Comments

I also tried it when I put it then my application is hang.. bcz that method is calling manytimes at time
one more thing this error is coming when i touch on map or any overlay otherwise it is working fine
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
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.

Comments

1
+50

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.