Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.util.ConcurrentModificationException in View.setVisibility

Tags:

I'm implementing drag'n'drop for views. When drag is started, I set visibility of the view to INVISIBLE, then, if the drag was interrupted - back to VISIBLE:

public boolean onTouch(View v, MotionEvent event) {     if (event.getAction() == MotionEvent.ACTION_DOWN) {         // Skipped some code         boolean dragStarted = v.startDrag(data, shadowBuilder, v, 0);          if (dragStarted) {             v.setVisibility(View.INVISIBLE)         }     } } 

And:

if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {     View droppedView = (View) event.getLocalState();     droppedView.setVisibility(View.VISIBLE); } 

And when "Drag ended" event is called, I'm getting exception:

E/AndroidRuntime(7118): FATAL EXCEPTION: main  E/AndroidRuntime(7118): java.util.ConcurrentModificationException  E/AndroidRuntime(7118):     at java.util.HashMap$HashIterator.nextEntry(HashMap.java:792) E/AndroidRuntime(7118):     at java.util.HashMap$KeyIterator.next(HashMap.java:819)  E/AndroidRuntime(7118):     at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1046) E/AndroidRuntime(7118):     at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048) E/AndroidRuntime(7118):     at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048) E/AndroidRuntime(7118):     at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048) E/AndroidRuntime(7118):     at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:3471) E/AndroidRuntime(7118):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2620) E/AndroidRuntime(7118):     at android.os.Handler.dispatchMessage(Handler.java:99)  E/AndroidRuntime(7118):     at android.os.Looper.loop(Looper.java:137)  E/AndroidRuntime(7118):     at android.app.ActivityThread.main(ActivityThread.java:4575) E/AndroidRuntime(7118):     at java.lang.reflect.Method.invokeNative(Native Method)  E/AndroidRuntime(7118):     at java.lang.reflect.Method.invoke(Method.java:511) E/AndroidRuntime(7118):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) E/AndroidRuntime(7118):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) E/AndroidRuntime(7118):     at dalvik.system.NativeStart.main(NativeMethod) 

Why and how to fix it?

like image 953
artem Avatar asked Jun 11 '12 23:06

artem


People also ask

How do I overcome Java Util ConcurrentModificationException?

How do you fix Java's ConcurrentModificationException? There are two basic approaches: Do not make any changes to a collection while an Iterator loops through it. If you can't stop the underlying collection from being modified during iteration, create a clone of the target data structure and iterate through the clone.

Can we get ConcurrentModificationException?

What Causes ConcurrentModificationException. The ConcurrentModificationException generally occurs when working with Java Collections. The Collection classes in Java are very fail-fast and if they are attempted to be modified while a thread is iterating over it, a ConcurrentModificationException is thrown.

What is ConcurrentModificationException and how it can be prevented?

The ConcurrentModificationException occurs when an object is tried to be modified concurrently when it is not permissible. This exception usually comes when one is working with Java Collection classes. For Example - It is not permissible for a thread to modify a Collection when some other thread is iterating over it.

What iterator can throw ConcurrentModificationException?

Iterator implementations that throw ConcurrentModificationException are known as fail-fast iterators, as they fail quickly and cleanly, rather than risking arbitrary, non-deterministic behavior later.


1 Answers

You can try this

if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {     final View droppedView = (View) event.getLocalState();     droppedView.post(new Runnable(){         @Override         public void run() {             droppedView.setVisibility(View.VISIBLE);         }     }); } 

Looks like Android itself trying to access View state at the same time as you end dragging.

EDIT

More precise explanation. By setting setVisibility(), you're including or excluding View from Android internal collection of views, that should respond to drag events. This collection is used during dispatch of drag events, and therefore by trying to setVisibility (in other words, trying to modify listeners of drag events) you're causing ConcurrentModificationException

like image 158
Dmitry Zaytsev Avatar answered Sep 26 '22 22:09

Dmitry Zaytsev