0

私のアプリケーションはAndroid1.6で正常に動作しますが、Android 2.2で実行すると、いくつかの場所でconcurrentModificationExceptionが発生します。何日も頭を包んだ後、私は理論を思いつきました。マルチスレッド(または同様のもの)が1.6から導入されたと思います。これでいいの?もしそうなら、マルチスレッドなしでアプリケーションを強制的に実行する方法はありますか?目標を1.6に設定しようとしましたが、運が悪かったです。よろしくお願いします。

例外:

04-05 11:47:12.812: ERROR/AndroidRuntime(5328): FATAL EXCEPTION: main
04-05 11:47:12.812: ERROR/AndroidRuntime(5328): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { cmp=ntnu.client/com.google.android.maps.MapView (has extras) }} to activity {ntnu.client/ntnu.client.MapClient}: java.util.ConcurrentModificationException
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3808)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3850)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.ActivityThread.access$2800(ActivityThread.java:136)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2209)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.os.Looper.loop(Looper.java:143)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.ActivityThread.main(ActivityThread.java:5068)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at java.lang.reflect.Method.invokeNative(Native Method)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at java.lang.reflect.Method.invoke(Method.java:521)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at dalvik.system.NativeStart.main(Native Method)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328): Caused by: java.util.ConcurrentModificationException
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at ntnu.client.MapClient.handleResult(MapClient.java:599)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at ntnu.client.MapClient.onActivityResult(MapClient.java:881)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.Activity.dispatchActivityResult(Activity.java:3988)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3804)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     ... 11 more

handleresult-codeを含むコードを以下に示します。

  public synchronized void handleResult(boolean notify)
  { 

      if(!citynodes.equals(null) && citynodes.size()>0 )
      {
          noteBaloon.setVisibility(0x00000008);

          Drawable drawable = this.getResources().getDrawable(R.drawable.up);
          Context myContext = this;

          itemizedoverlay = new CitynodeItemizedOverlay(drawable,myContext);
          itemizedoverlay.setThumbsUp(BitmapFactory.decodeResource(
                  getResources(), R.drawable.vote_yes3));  

          itemizedoverlay.setThubmsDown(BitmapFactory.decodeResource(
                  getResources(), R.drawable.vote_no3));  
          itemizedoverlay.addObserver(this);    

          //itemizedoverlay.setDoAnimtation(true);

          RecommendationNotificationOverlay overlay = new RecommendationNotificationOverlay(); 


          for (Recommendation n : citynodes )
          {

              CitynodeOverlayItem cn= n.getNode().getOverlayItem();
              Drawable marker =  this.iconmanager.changeBackground(this.iconmanager.findIcon(n.getNode()),Integer.parseInt(n.getSystemRating()),n.isPersonalized()); 
              //marker.setAlpha(100);
              marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight());

              ShapeDrawable l; 

              cn.setMarker(marker); 
              cn.setNode(n);
              itemizedoverlay.addOverlay(cn);

              LayoutInflater inflater = getLayoutInflater();
          }



          for(Overlay i : getMapView().getOverlays() )
          { 
              if((i instanceof ItemizedOverlay)) //|| (i instanceof RecommendationNotificationOverlay) )
                  this.mapView.getOverlays().remove(i); 
          }



          for(Overlay i : getMapView().getOverlays() )
          { 
              if((i instanceof RecommendationNotificationOverlay) )
                  this.mapView.getOverlays().remove(i); 
          }
          List <Recommendation> proactive = new ArrayList<Recommendation>(); 

          for(Recommendation potpro : this.citynodes)
          {
              if(potpro.isProactive())
              {
                  proactive.add(potpro); 

              }

          }

          overlay.setNotifications(proactive); 

          mapOverlays.add(overlay);



          mapOverlays.add(itemizedoverlay);



          mapView.invalidate();

      }

  }  

この例外が参照するコードは、最初のforループです。

  for(Overlay i : getMapView().getOverlays() )

このコードは、この行にも同じ例外をスローします(別のアクションを処理します)。

  if(!citynodes.equals(null) && citynodes.size()>0 )
4

3 に答える 3

1

ああ、あなたの問題の少なくとも1つは、マルチスレッドとは何の関係もありません。

for(Overlay i : getMapView().getOverlays() )
{ 
    if (i instanceof ItemizedOverlay)
        this.mapView.getOverlays().remove(i); 
}

このスタイルのforループを使用してコレクションを反復処理している間は、コレクションを変更できません。コレクションの実装が気付かず、それを回避できる場合もありますが、Androidのある時点でコレクションの実装が変更され、この種の問題が発生した可能性があります。ループ中にアイテムを削除する場合は、を取得してそれを使用してループし、を呼び出す必要がありIteratorます。removeIterator

for(Iterator<Overlay> it=getMapView().getOverlays().iterator(); it.hasNext(); )
{
    Overlay i = it.next(); 
    if (i instanceof ItemizedOverlay)
        it.remove(); 
}

またはその効果への何か。

于 2011-04-06T09:29:07.247 に答える
0

これは、関心のあるエラーメッセージの一部です。

04-05 11:47:12.812: ERROR/AndroidRuntime(5328): Caused by: java.util.ConcurrentModificationException
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at ntnu.client.MapClient.handleResult(MapClient.java:599)
04-05 11:47:12.812: ERROR/AndroidRuntime(5328):     at ntnu.client.MapClient.onActivityResult(MapClient.java:881)

このエラーは、handleResultmethdのMapClientクラスの599行目で発生します。メソッドからコードを投稿できますhandleResultか?

例外は、複数のスレッドが同時にArrayListを変更しようとしているために発生します。

于 2011-04-05T10:40:16.233 に答える
0

配列のコンテンツを変更する領域をsychronized([ArrayList]){}でラップします。そうすれば、スレッドは両方とも配列の内容を変更できます

于 2011-04-05T10:46:51.743 に答える