2012-02-12 92 views
0

我已經建立了谷歌api MapView演示。MapView ConcurrentModificationException當更新覆蓋

我已經擴展MapView類來創建一個「onPanListener」類似於: How to catch that map panning and zoom are really finished?

我還創建了類似的GroundOverlay類: Android google maps groundoverlay

我竭力要弄清楚爲什麼我有時會遇到ConcurrentModificationException。我懷疑這可能是因爲我最終得到了兩個定時器觸發的panlisteneres,它們在覆蓋列表中執行並導致併發訪問問題。但是,我不知道這是否是問題。我曾嘗試在刪除或向疊加列表添加任何內容的任何代碼上添加synchronized(mapview.getOverlay()){}。

我有我的堆棧跟蹤下面列出,但我不知道該怎麼做。它看起來像例外可能從我的GroundOverlay類從draw方法開始(但我不確定)。當我刪除groundoverlay,我不認爲我得到ConcurrentModificationException - 有點難以分辨,因爲它是一個間歇的事情。

堆棧跟蹤似乎表明它來自mapview.draw方法。我想也許我可以在我的mapview子類中重寫該方法並嘗試並同步該方法,但不幸的是,繪製在父類中是最終的。同步dispatchDraw似乎沒有幫助。

有沒有更好的方法來調試這樣的東西?也許可以以某種方式獲得有關異常的更多信息 - 只要知道我的代碼的哪一行將會引發極大的幫助。

我已經試過同步

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) 

這是我OnChangeListener。根據評論,這聽起來像清除和重寫疊加並不是最好的選擇。也許,而不是試圖從我的MapView類獲取onpan事件,我應該真的從我的擴展OverlayItem類中獲取它?我可以嘗試一下。

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


     } 
    }); 

} 

這裏的xxx.addOverlays(視圖)的代碼

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

} 
+1

請顯示您的代碼 - 不是'ConcurrentModificationException'有一點混淆,因爲它並不一定意味着涉及多個線程。 – 2012-02-12 19:09:51

+0

你見過http://stackoverflow.com/questions/2870743/android-2-1-googlemaps-itemizedoverlay-concurrentmodificationexception了嗎? – 2012-02-12 19:10:38

回答

2

通過Android 2.1 GoogleMaps ItemizedOverlay ConcurrentModificationException更徹底地看完後,我得出的結論,我的問題是事實,我正在啓動一個新的線程對於添加和刪除疊加項目的定時器,這會間歇性地導致併發接收錯誤。

我最終把修改覆蓋層的代碼放在Activity.runOnUiThread(...)中,並且自那之後就沒有看到這個問題。

+0

謝謝,你也解決了我的問題。 :) – 2013-02-02 12:45:04