gpt4 book ai didi

Android - setVisibility 导致 java.util.ConcurrentModificationException

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:56:32 24 4
gpt4 key购买 nike

我正在通过 setVisibility(View.INVISIBLE) 隐藏 View 。稍后,当我尝试通过 setVisibility(View.VISIBLE) 以不同的方法再次显示 View 时,出现以下异常

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)

当我注释掉将可见性改回可见的行时,我没有得到异常。

我一开始以为是其他一些代码遍历hashmap导致的异常,然而,我在遍历我使用的hashmap时没有做任何修改,我也没有多线程,这似乎是最此异常的常见原因。当我不改变可见性时,我也没有得到异常。

编辑:
异常发生在自定义 fragment 中。下面是我迭代散列图 (mWidgetConfig) 的代码,它包含有关我尝试恢复的自定义小部件的配置信息。 HashMap 是 fragment 中的公共(public)变量。

在 fragment 创建的OnDragListener中,我根据某个拖动操作更新hashmap,如下所示:

// Update the widget configuration of the fragment that created this listener
mFragment.mWidgetConfig.put(startCircleTag, "0");

我还遍历 hashmap 以检查特定条件,但我在迭代期间不做任何修改:

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;

}
}

此外,我在尝试恢复小部件配置时在 fragment 本身中进行了一次迭代。下面是我用来根据 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());
}

只要在代码中使用设置上面“插头”可见性的行,我就会得到异常。

解决方案
抛出异常的原因是我调用了 OnDragListenerDragEvent.ACTION_DRAG_ENDED case 语句中的配置方法。当我将相同的代码放入 DragEvent.ACTION_DROP case 语句时,不会抛出异常。不知道为什么。谢谢大家的帮助

最佳答案

据我了解,这是由 ViewGroup 实现细节引起的。并且与多线程无关。

当拖动开始时,ViewGroup 创建一个必须通知有关 ACTION_DRAG_ENDED 事件的 subview 的 HashSet。这是一组可见的 child 。当子项可见性发生变化时,相应的 ViewGroup 会修改该集合(如果其可见性为 VISIBLE,则添加一个子项)。在您的情况下,它发生在该集合的迭代过程中。

想一想,对您来说最简单的解决方案是推迟可见性更改。

view.post(new Runnable() {
public void run() {
view.setVisibility(View.VISIBLE);
}
});

当您将代码放入 ACTION_DROP case 语句时,不会发生异常,因为在您更改 View 可见性时该集合未被迭代。

有关详细信息,请参阅 ViewGroup.dispatchDragEvent(DragEvent)源代码。

关于Android - setVisibility 导致 java.util.ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9899382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com