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

【问题】

相关代码: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

参考:

可以使用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

了。解决办法是:

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