Android从1.6升级到2.2会导致异常



我的应用程序在Android 1.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();
      }
  }  

这个Exception引用的代码是第一个for循环:

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

代码也在这一行抛出相同的Exception(处理另一个操作):

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

啊,至少有一个问题与多线程无关:

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

不能在使用这种类型的for循环遍历集合时修改它。有时候,集合的实现不会注意到,你会侥幸逃脱,但我怀疑集合的实现可能在Android的某个时候被改变了,这样就可以捕捉到这种事情。如果你想在循环时删除项目,你需要获得一个Iterator并使用它来循环,在Iterator上调用remove

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

这是您感兴趣的错误消息的一部分:

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)

错误发生在handleResult方法中MapClient类的第599行。你能把你的handleResult方法的代码贴出来吗?

此异常是由于多个线程同时试图修改ArrayList而导致的

wrap synchronized ([ArrayList]){}在你修改Array内容的地方。这样两个线程都可以改变Array的内容

最新更新