MapView 上的 java.util.ConcurrentModificationException

发布于 2025-01-06 17:22:23 字数 5925 浏览 1 评论 0原文

伙计们,

我很多天都面临着非常奇怪的问题。我正在尝试经常更新覆盖。因此,有时当我触摸地图时,我会收到“java.util.ConcurrentModificationException”,或者有时当地图尝试更新叠加层时,我会收到“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()" 上抛出错误,因为它在 1 秒内调用 4-5 次。

谢谢,

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

        }
    });
}

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

        }
    });
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

许久 2025-01-13 17:22:23

为了避免 ConcurrentModificationException,只需在以下任何情况下复制您的集合:

  • 在迭代集合
  • 之前 将其传递到 API

乍一看,这可能看起来有些过头,但它会为您节省很多后来头痛。复制很简单,只需调用new ArrayList(existingList)即可。

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

梅倚清风 2025-01-13 17:22:23

我认为您使用 Thread 及其创建 Concurrency 因此,在您的运行方法中使用 Syncronized(MainActivity.this) ....并使用 Vector 代替列表因为 Vector 是同步的...它对我有用...

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

撩动你心 2025-01-13 17:22:23

好吧,看来在您的 updateMethod() 中,您仍在尝试通过 Non-UI 线程更新您的 UI

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

,所以,尝试在 RunOnUiThread 中执行这部分代码并尝试。希望这会起作用。

UPDATE:

另外,为什么您要尝试添加删除您的覆盖所有内容,您不需要这样做,只需尝试更新您的>覆盖使其无效看看这个示例。

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.

一紙繁鸢 2025-01-13 17:22:23

我不确定覆盖管理,但在我看来,您正在非 UI 线程(在 UpdateMethod 中)上使用 HashMap.put 修改 HashMap,而毫无疑问它会被迭代或在其他地方使用。应用程序 - 可能在您移动地图时仍在请求新的叠加层时。

如果您阅读 docs,它说这将导致 ConcurrentModificationException。相反,尝试使用 ConcurrentHashMap,或重构代码以更新使用它的主线程上的哈希图。

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.

仅冇旳回忆 2025-01-13 17:22:23

是的,你可以解决这个问题,
步骤如下。

  1. 创建一个 Pendingnotification 类(修改详细信息)。
  2. 列出待处理通知。
  3. 当任何通知接收到不直接修改它时,收集所有修改并放入堆栈(Pendingnotification 类)即。将其添加到待处理通知列表中。
  4. 现在,一一修改对象并在工作完成后删除同一对象。

以同样的方式进行操作,直到待处理通知列表变空。

另请注意,任何修改都必须在 UI Thread 中执行,而不是在 NonUI Thread 中执行

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文