最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Android的Java代码中使用for循环期间去修改被循环的变量结果出错:Caused by: java.util.ConcurrentModificationException

Java crifan 5899浏览 0评论

【问题】

相关代码:

 private void addDevicedapterToList(IAdapter deviceAdapter) {
...
   for (AdapterItem tmp : deviceAdapters) {
    if (tmp.getName().equals(item.getName())) {
     //tmp.setSignal(item.getSignal());
     //return;
     
     //if found existing one, remove first then later add
     // -> to ensue latest scanned device, especially Bluetooth device is ACTIVE one
     deviceAdapters.remove(tmp);
    }
   }

运行时出错:

04-13 09:37:10.492: D/dalvikvm(13937): GC_CONCURRENT freed 282K, 11% free 7529K/8391K, paused 14ms+3ms, total 43ms
04-13 09:37:10.594: D/AbsListView(13937): Get MotionRecognitionManager
04-13 09:37:10.735: D/libEGL(13937): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
04-13 09:37:10.742: D/libEGL(13937): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
04-13 09:37:10.750: D/libEGL(13937): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
04-13 09:37:10.875: D/OpenGLRenderer(13937): Enabling debug mode 0
04-13 09:37:32.875: D/AndroidRuntime(13937): Shutting down VM
04-13 09:37:32.875: W/dalvikvm(13937): threadid=1: thread exiting with uncaught exception (group=0x41a492a0)
04-13 09:37:32.922: E/AndroidRuntime(13937): FATAL EXCEPTION: main
04-13 09:37:32.922: E/AndroidRuntime(13937): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.bluetooth.device.action.FOUND flg=0x10 (has extras) } in xxx.yyy.zzz.Bluetooth.Bluetooth$2@4223f0f0
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:765)
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.os.Handler.handleCallback(Handler.java:615)
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.os.Handler.dispatchMessage(Handler.java:92)
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.os.Looper.loop(Looper.java:137)
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.app.ActivityThread.main(ActivityThread.java:4895)
04-13 09:37:32.922: E/AndroidRuntime(13937): at java.lang.reflect.Method.invokeNative(Native Method)
04-13 09:37:32.922: E/AndroidRuntime(13937): at java.lang.reflect.Method.invoke(Method.java:511)
04-13 09:37:32.922: E/AndroidRuntime(13937): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
04-13 09:37:32.922: E/AndroidRuntime(13937): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
04-13 09:37:32.922: E/AndroidRuntime(13937): at dalvik.system.NativeStart.main(Native Method)
04-13 09:37:32.922: E/AndroidRuntime(13937): Caused by: java.util.ConcurrentModificationException
04-13 09:37:32.922: E/AndroidRuntime(13937): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.UI.AdapterActivity.addDevicedapterToList(AdapterActivity.java:316)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.UI.AdapterActivity.access$4(AdapterActivity.java:307)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.UI.AdapterActivity$3.run(AdapterActivity.java:173)
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.app.Activity.runOnUiThread(Activity.java:4741)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.UI.AdapterActivity.onEvent(AdapterActivity.java:164)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.CommonLib.EventCenter.Subject.publish(Subject.java:17)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.BLL.NetworkEnvironment$FoundSingleAdapter.Execute(NetworkEnvironment.java:203)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.BLL.NetworkEnvironment$FoundSingleAdapter.Execute(NetworkEnvironment.java:1)
04-13 09:37:32.922: E/AndroidRuntime(13937): at xxx.yyy.zzz.Bluetooth.Bluetooth$2.onReceive(Bluetooth.java:353)
04-13 09:37:32.922: E/AndroidRuntime(13937): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:755)

【解决过程】

1.感觉像是:

在for循环里面,修改了要循环的变量。

所以导致了:

ConcurrentModificationException

所以去搜:

java for loop ConcurrentModificationException

参考:

java.util.ConcurrentModificationException in For loop – Stack Overflow

可以使用Iterator实现:

在被循环的list等集合中,去除某个item。

2.代码改为:

 private void addDevicedapterToList(IAdapter deviceAdapter) {
  AdapterItem item = null;
  boolean needRemoveCurExisting = false;
  int curExistingItemIdx = 0;
        ......
   //for (AdapterItem tmpItem : deviceAdapters) {
   for (int idx=0; idx < deviceAdapters.size(); idx++) {
    AdapterItem tmpItem = deviceAdapters.get(idx);
    if (tmpItem.getName().equals(item.getName())) {
     //tmpItem.setSignal(item.getSignal());
     //return;
     
     //if found existing one, remove first then later add
     // -> to ensue latest scanned device, especially Bluetooth device is ACTIVE one
     //deviceAdapters.remove(tmpItem);
     needRemoveCurExisting = true;
     curExistingItemIdx = idx;
     break;
    }
   }
           
   if(needRemoveCurExisting){
    deviceAdapters.remove(curExistingItemIdx);
   }

即可解决并发访问的问题。

 

【总结】

java中,在(for等)循环中,的确是不能直接修改被循环(遍历)的值的,否则就会出现并发修改值的问题:

ConcurrentModificationException

了。解决办法是:

可以记录一下要修改的值,在遍历之后,再去修改。

转载请注明:在路上 » 【已解决】Android的Java代码中使用for循环期间去修改被循环的变量结果出错:Caused by: java.util.ConcurrentModificationException

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
92 queries in 0.180 seconds, using 23.34MB memory