3

フェラ

私は何日もの間、非常に奇妙な問題に直面しています。オーバーレイを頻繁に更新しようとしています。そのため、マップに触れたときに「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)
                {}              

        }
    });
}
4

5 に答える 5

2

ConcurrentModificationException次のいずれかの場合にコレクションを単純にコピーしないようにするには:

  • コレクションを反復処理する前に
  • API に渡す前に

一見、これはやり過ぎのように思えるかもしれませんが、後で頭痛の種を大幅に減らすことができます。コピーは簡単です。 を呼び出すだけnew ArrayList<YourClass>(existingList)です。

于 2012-02-17T10:28:51.907 に答える
1

ya、あなたは回避策を行うことができます、次のようにステップします。

  1. 保留中の通知クラス(変更の詳細)を作成します。
  2. 保留中の通知のリストを作成します。
  3. 通知を受け取ったら、それを直接変更し、すべての変更を収集してスタック(Pendingnotificationクラス)を配置します。保留中の通知リストに追加します。
  4. これで、オブジェクトを1つずつ変更し、作業が完了したら同じオブジェクトを削除します。

保留中の通知リストが空になるまで同じ方法に従います。

UI Threadまた、変更はではなくで実行する必要があることにも注意してくださいNonUI Thread

于 2012-02-27T07:01:22.560 に答える
1

私はあなたが使用Threadし、その作成を使用すると思いますConcurrencyのでSyncronized(MainActivity.this)、実行方法で使用します....そして、ベクトルは同期されているため、リストの代わりにベクトルを使用します...私にとってはうまくいきます...

于 2012-02-17T09:58:14.940 に答える
1

オーバーレイ管理についてはよくわかりませんが、私が見ているように、非 UI スレッド (UpdateMethod 内) で HashMap.put を使用して HashMap を変更しています。アプリ - おそらく、マップを移動するときに新しいオーバーレイをまだリクエストしているときに発生します。

docsを読むと、これにより ConcurrentModificationException が発生すると書かれています。代わりに、ConcurrentHashMapを使用するか、コードを再構築して、使用されているメイン スレッドでハッシュマップを更新してください。

于 2012-02-25T05:23:15.007 に答える
1

さて、updateMethod()あなたはまだスレッドUpdateから UI にアクセスしようとしているようです。Non-UI

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

したがって、コードのこの部分を 内で実行してみてRunOnUiThreadください。これがうまくいくことを願っています。

UPDATE:

また、なぜあなたはあなたのすべてを更新しようaddとしているのか、それをする必要はありません。removeOverlayOverlayinvalidateHave a look at this example.

于 2012-02-20T06:10:14.353 に答える