Android — setVisibility приводит к исключению java.util.ConcurrentModificationException

Я скрываю представление через 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), содержащую информацию о конфигурации пользовательских виджетов, которые я пытаюсь восстановить. Хэш-карта — это общедоступная переменная во фрагменте.

В OnDragListener, созданном фрагментом, я обновляю хэш-карту в соответствии с определенной операцией перетаскивания, например:

// 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;

            }
        }

Кроме того, я делаю одну итерацию в самом фрагменте, пытаясь восстановить конфигурацию виджета. Ниже приведен код, который я использую для настройки виджета в соответствии с хэш-картой:

    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());
}

Как только в коде используются строки, устанавливающие видимость «заглушек» выше, я получаю исключение.

РЕШЕНИЕ
Причина возникновения исключения заключается в том, что я вызвал методы конфигурации в DragEvent.ACTION_DRAG_ENDEDcase операторе OnDragListener. Когда я помещаю тот же код в оператор case DragEvent.ACTION_DROP, исключение не генерируется. Не знаю, почему. Спасибо за помощь, ребята

8
задан Schnodahipfe 29 March 2012 в 15:34
поделиться