更新覆盖时的MapView ConcurrentModificationException的 [英] MapView ConcurrentModificationException when updating overlays

查看:116
本文介绍了更新覆盖时的MapView ConcurrentModificationException的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经建立了谷歌的API MapView的演示。

我伸出的MapView类来创建一个onPanListener类似于:
<一href=\"http://stackoverflow.com/questions/3567420/how-to-catch-that-map-panning-and-zoom-are-really-finished\">How赶上那地图平移和缩放真的完了吗?

我还创建了一个类似的GroundOverlay类:
Android版谷歌地图的GroundOverlay

我竭力要弄清楚为什么我有时会得到一个ConcurrentModificationException的。我怀疑这可能是因为我结束了与覆盖列表上执行,并导致并发访问问题个定时器触发panlisteneres。但是,我不知道如果是这样的问题或没有。我曾尝试加入同步(mapview.getOverlay()){}任何code,消除或添加任何东西覆盖列表。

我有我的堆栈跟踪下面列出的,但我不能完全肯定它来做什么。它看起来像例外,从抽签的方法我的GroundOverlay类也许开始的(但我不知道)。当我删除的GroundOverlay,我不知道的认为的我得到的ConcurrentModificationException的 - 位很难讲,因为它是一个间歇性的东西。

堆栈跟踪似乎表明它是从mapview.draw方法来。我想也许我可以覆盖在我的图形页面的子类,方法和尝试,并同步了,但不幸的是,平局是最终的父类。同步dispatchDraw似乎并没有帮助。

有没有更好的办法来调试这样的事情?也许得到关于异常更多的信息以某种方式 - 只知道什么线我的code的抛出这将是非常有用的。

我曾尝试同步

  10月2日至12日:59:31.995:E / AndroidRuntime(24649):致命异常:主要10月2日至12日:59:31.995:E / AndroidRuntime(24649):java.util.ConcurrentModificationException
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在java.util.ArrayList中$ ArrayListIterator.next(ArrayList.java:576)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:44)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在com.google.android.maps.MapView.onDraw(MapView.java:530)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.View.draw(View.java:6880)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewGroup.drawChild(ViewGroup.java:1646)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.View.draw(View.java:6883)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.widget.FrameLayout.draw(FrameLayout.java:357)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewGroup.drawChild(ViewGroup.java:1646)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.View.draw(View.java:6883)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.widget.FrameLayout.draw(FrameLayout.java:357)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在com.android.internal.policy.impl.PhoneWindow $ DecorView.draw(PhoneWindow.java:2106)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewRoot.draw(ViewRoot.java:1562)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewRoot.performTraversals(ViewRoot.java:1298)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.view.ViewRoot.handleMessage(ViewRoot.java:1911)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.os.Handler.dispatchMessage(Handler.java:99)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.os.Looper.loop(Looper.java:130)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在android.app.ActivityThread.main(ActivityThread.java:3821)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在java.lang.reflect.Method.invokeNative(本机方法)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在java.lang.reflect.Method.invoke(Method.java:507)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:839)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
10月2日至12日:59:31.995:E / AndroidRuntime(24649):在dalvik.system.NativeStart.main(本机方法)

下面是我的OnChangeListener。根据该意见,这听起来像结算和重写覆盖是不是最好的选择。也许,而不是试图从我的MapView类获得onpan事件,我真的应该从我的扩展OverlayItem类得到它?我也许可以试试。

  mMapView.setOnChangeListener(新MyMapView.OnChangeListener(){        @覆盖
        公共无效的onChange(Metars每小时一次,PIREPS PIREP,MyMapView认为,的GeoPoint newCenter,GeoPoint的oldCenter,
                INT newZoom,诠释oldZoom){            //metar.addOverlays(view);
            如果(view.updatingOverlay == FALSE){
                view.updatingOverlay = TRUE;
                同步(view.getOverlays()){
                    。view.getOverlays()清();
                    。view.getOverlays()加(view.getRadar());
                }
                metar.addOverlays(视图);
                pirep.addOverlays(视图);
                view.postInvalidate();
                view.updatingOverlay = FALSE;
            }
        }
    });}

这里的code为xxx.addOverlays(视图)

 公共无效addOverlays(MyMapView MapView类){          //做了一堆东西,并得到覆盖准备添加
    清单&LT;&叠加GT; mapOverlays =调用MapView.getOverlays();    //将它们添加到我的ItemizedOverlay的子类    同步(mapOverlays){
    如果(itemizedoverlay.size()大于0)
        mapOverlays.add(itemizedoverlay);
    }}


解决方案

到<一看完后href=\"http://stackoverflow.com/questions/2870743/android-2-1-googlemaps-itemizedoverlay-concurrentmodificationexception\">Android 2.1的GoogleMaps ItemizedOverlay ConcurrentModificationException的的更彻底,我得出的结论,我的问题是事实,我被推出了哪些添加和删除叠加物品的计时器,它会间歇性地引起concurrentacccessexception一个新的线程。

我最终把code修改Activity.runOnUiThread(...)内的覆盖和由于还没有看到这个问题。

I have built off of the google api MapView demo.

I've extended the MapView class to create a "onPanListener" similar to: How to catch that map panning and zoom are really finished?

I've also created a GroundOverlay class similar to: Android google maps groundoverlay

I'm struggling to figure out why I sometimes get a ConcurrentModificationException. I suspect it might be because I end up with two timer triggered panlisteneres that execute and cause concurrent access issues on the overlay list. However, I can't tell if that is the problem or not. I have tried adding synchronized (mapview.getOverlay()) {} on any code that removes or adds anything to the overlay list.

I have my stack trace listed below, but I'm not exactly sure what to make of it. It looks like the exception maybe starts in my GroundOverlay class from the draw method (but I'm not sure). When I remove the groundoverlay, I don't think I get the ConcurrentModificationException -- bit tough to tell since it is an intermittent thing.

The stack trace does seem to suggest it is coming from the mapview.draw method. I thought maybe I could override that method in my mapview subclass and try and synchronize that, but unfortunately, draw is final in the parent class. Synchronizing dispatchDraw doesn't seem to help.

Is there a better way to debug something like this? Maybe get some more information about the exception somehow -- just knowing what line of my code throws it would be enormously helpful.

I have tried synchronizing

02-12 10:59:31.995: E/AndroidRuntime(24649): FATAL EXCEPTION: main

02-12 10:59:31.995: E/AndroidRuntime(24649): java.util.ConcurrentModificationException
02-12 10:59:31.995: E/AndroidRuntime(24649):    at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:44)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at com.google.android.maps.MapView.onDraw(MapView.java:530)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.View.draw(View.java:6880)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.View.draw(View.java:6883)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.widget.FrameLayout.draw(FrameLayout.java:357)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.View.draw(View.java:6883)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.widget.FrameLayout.draw(FrameLayout.java:357)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2106)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewRoot.draw(ViewRoot.java:1562)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewRoot.performTraversals(ViewRoot.java:1298)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1911)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.os.Looper.loop(Looper.java:130)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at android.app.ActivityThread.main(ActivityThread.java:3821)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at java.lang.reflect.Method.invokeNative(Native Method)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at java.lang.reflect.Method.invoke(Method.java:507)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-12 10:59:31.995: E/AndroidRuntime(24649):    at dalvik.system.NativeStart.main(Native Method)

Here is my OnChangeListener. Based on the comment, it sounds like clearing and rewriting the overlays isn't the best option. Maybe, instead of trying to get the onpan event from my MapView class, I should really be getting it from my extended OverlayItem class? I can probably try that.

mMapView.setOnChangeListener(new MyMapView.OnChangeListener() {

        @Override
        public void onChange(Metars metar, Pireps pirep, MyMapView view, GeoPoint newCenter, GeoPoint oldCenter,
                int newZoom, int oldZoom) {

            //metar.addOverlays(view);
            if (view.updatingOverlay == false) {
                view.updatingOverlay = true;
                synchronized (view.getOverlays() ) {
                    view.getOverlays().clear();
                    view.getOverlays().add(view.getRadar());
                }
                metar.addOverlays(view);
                pirep.addOverlays(view);
                view.postInvalidate();
                view.updatingOverlay = false;
            }


        }
    });

}

Here's the code for the xxx.addOverlays(view)

public void addOverlays(MyMapView mapView) {

          // do a bunch of stuff and get overlays ready to add
    List<Overlay> mapOverlays = mapView.getOverlays();

    // add them to my subclass of ItemizedOverlay

    synchronized(mapOverlays) {
    if (itemizedoverlay.size() > 0 )
        mapOverlays.add(itemizedoverlay);
    }

}

解决方案

After reading through Android 2.1 GoogleMaps ItemizedOverlay ConcurrentModificationException more thoroughly, I came to the conclusion that my issue was the fact that I was launching a new thread for the timer which added and removed overlay items, which would intermittently cause the concurrentacccessexception.

I ended up putting the code modifying the overlays inside an Activity.runOnUiThread(...) and haven't seen the problem since.

这篇关于更新覆盖时的MapView ConcurrentModificationException的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆