Java.util.ConcurrentModificationException в View.setVisibility
Я использую drag'n'drop для просмотров. Когда началось перетаскивание, я установил видимость представления в INVISIBLE
, затем, если перетащить было прервано - вернитесь к 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)
}
}
}
и
if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {
View droppedView = (View) event.getLocalState();
droppedView.setVisibility(View.VISIBLE);
}
И когда вызывается событие "Перетаскивание", я получаю исключение:
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)
Почему и как его исправить?
Ответы
Ответ 1
Вы можете попробовать это
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);
}
});
}
Похоже, что сам Android пытается получить доступ к представлению в то же время, что и вы перетаскиваете.
ИЗМЕНИТЬ
Более точное объяснение. Установив setVisibility()
, вы включаете или исключаете View
из внутренней коллекции просмотров Android, которая должна реагировать на события перетаскивания. Эта коллекция используется при отправке событий перетаскивания и, следовательно, при попытке setVisibility
(другими словами, при попытке изменить прослушиватели событий перетаскивания) вы вызываете ConcurrentModificationException
Ответ 2
Лучший способ это:
view.post(new Runnable() {
public void run() {
view.setVisibility(View.VISIBLE);
}
});
если мы используем:
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);
}
});
}
вы все равно получите силу при закрытии Null.pointer....
Ответ 3
Возможно, этот может помочь. здесь в данной ссылке говорится: вместо DragEvent.ACTION_DRAG_ENDED
используйте DragEvent.ACTION_DROP
.