【问题】
相关代码:
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