【发布时间】:2012-03-27 23:58:53
【问题描述】:
我正在通过setVisibility(View.INVISIBLE) 隐藏视图。稍后当我尝试通过 setVisibility(View.VISIBLE) 以不同的方法再次显示视图时,我得到以下异常
03-28 01:32:05.450: E/AndroidRuntime(20895): FATAL EXCEPTION: main
03-28 01:32:05.450: E/AndroidRuntime(20895): java.util.ConcurrentModificationException
03-28 01:32:05.450: E/AndroidRuntime(20895): at java.util.HashMap$HashIterator.nextEntry(HashMap.java:796)
03-28 01:32:05.450: E/AndroidRuntime(20895): at java.util.HashMap$KeyIterator.next(HashMap.java:823)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:946)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:948)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:948)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:948)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:948)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:948)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewRoot.handleDragEvent(ViewRoot.java:3027)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.view.ViewRoot.handleMessage(ViewRoot.java:2185)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.os.Handler.dispatchMessage(Handler.java:99)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.os.Looper.loop(Looper.java:132)
03-28 01:32:05.450: E/AndroidRuntime(20895): at android.app.ActivityThread.main(ActivityThread.java:4028)
03-28 01:32:05.450: E/AndroidRuntime(20895): at java.lang.reflect.Method.invokeNative(Native Method)
03-28 01:32:05.450: E/AndroidRuntime(20895): at java.lang.reflect.Method.invoke(Method.java:491)
03-28 01:32:05.450: E/AndroidRuntime(20895): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
03-28 01:32:05.450: E/AndroidRuntime(20895): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
03-28 01:32:05.450: E/AndroidRuntime(20895): at dalvik.system.NativeStart.main(Native Method)
当我注释掉将可见性更改回可见的行时,我没有得到异常。
我首先认为异常可能是由一些其他代码迭代哈希图引起的,但是,我在迭代我使用的哈希图时没有做任何修改,我也没有多线程,这似乎是最此异常的常见原因。当我不改变可见性时,我也没有得到例外。
编辑:
异常发生在自定义片段中。下面是我迭代哈希图 (mWidgetConfig) 的代码,其中包含有关我要恢复的自定义小部件的配置的信息。 hashmap 是片段中的公共变量。
在一个由fragment创建的OnDragListener中,我根据一定的拖拽操作更新hashmap,如下:
// Update the widget configuration of the fragment that created this listener
mFragment.mWidgetConfig.put(startCircleTag, "0");
我还遍历哈希图以检查某个条件,但在迭代期间我没有做任何修改:
Iterator<String> keySetItr = mFragment.mWidgetConfig.keySet().iterator();
while(keySetItr.hasNext()) {
String tag = keySetItr.next();
if(mFragment.mWidgetConfig.get(tag).equals((String) destSocket.getTag())) {
// do something, though no modification of the hashmap
break;
}
}
此外,我在尝试恢复小部件配置时对片段本身进行了一次迭代。下面是我用来根据 hashmap 配置小部件的代码:
public void configureWidgets() {
resetWidgets();
Iterator<String> keySetItr = mWidgetConfig.keySet().iterator();
while(keySetItr.hasNext()) {
String tag = keySetItr.next();
Integer value = Integer.parseInt(mWidgetConfig.get(tag));
ImageView destSocket = null;
switch(value) {
case 0:
// The circle will not be connected to any socket
continue;
case 1:
destSocket = mSocket1;
break;
case 2:
destSocket = mSocket2;
break;
case 3:
destSocket = mSocket3;
break;
}
ImageView startCircle = (ImageView) mLayout.findViewWithTag(tag);
ImageView startPlug = (ImageView) mLayout.findViewWithTag(tag + "_plug");
// Replace the drawable of destSocket
destSocket.setBackgroundDrawable(getActivity().getResources().getDrawable(R.drawable.socket_plugged));
// Hide plug view
startPlug.setVisibility(View.INVISIBLE);
// Draw a line between the start circle view and the destination socket view
mConnectionLinesView.addLine(startCircle, destSocket);
}
}
public void resetWidgets() {
// Remove all lines
mConnectionLinesView.removeLines();
// Show all eventually previously hidden plugs
//mPlug1.setVisibility(View.VISIBLE);
//mPlug2.setVisibility(View.VISIBLE);
//mPlug3.setVisibility(View.VISIBLE);
// Set to backround drawable of the socket to the initial one
mSocket1.setBackgroundDrawable(getActivity().getResources().getDrawable(R.drawable.socket).mutate());
mSocket2.setBackgroundDrawable(getActivity().getResources().getDrawable(R.drawable.socket).mutate());
mSocket3.setBackgroundDrawable(getActivity().getResources().getDrawable(R.drawable.socket).mutate());
}
只要在代码中使用了设置上述“插头”可见性的行,就会出现异常。
解决方案
抛出异常的原因是我调用了OnDragListener 的DragEvent.ACTION_DRAG_ENDED case 语句中的配置方法。当我将相同的代码放入DragEvent.ACTION_DROP case 语句时,不会引发异常。不知道为什么。谢谢你们的帮助
【问题讨论】:
-
发布您的代码以迭代 hashmap ...并创建此异常
-
那么为什么只有在我更改可见性时才抛出异常?
-
是删除或添加
while(iterator.hasNext()) -
不,没有,这很奇怪:(
-
会有所帮助,但使用 HashMap 的部分是实际的 Android 代码 ;)