我在I used synchronized list, and i still get ConcurrentModificationException找到了同样的问题,但我找不到正确答案。
以下是我定义synchronized
列表的方式:
private List<ActionItemClickListener> actionItemClickListeners = Collections.synchronizedList(new ArrayList<ActionItemClickListener>());
以下是我如何使用它:
@Override
public void onBackPressed() {
boolean isConsume = false;
synchronized (actionItemClickListeners) {
//ConcurrentModificationException occur here
for (ActionItemClickListener listener : actionItemClickListeners) {
isConsume = isConsume | listener.onSystemBackPressed();
}
}
if(!isConsume) {
pendingFragment = null;
pendingTag = null;
currentFragmentTag = null;
super.onBackPressed();
}
}
public void addActionItemClickListener(ActionItemClickListener listener) {
synchronized (actionItemClickListeners) {
if (listener != null)
actionItemClickListeners.add(listener);
}
}
public void removeActionItemClickListener(ActionItemClickListener listener) {
synchronized (actionItemClickListeners) {
if (listener != null)
actionItemClickListeners.remove(listener);
}
}
为什么我仍然得到ConcurrentModificationException
???
答案 0 :(得分:2)
您的ConcurrentModificationException
不是线程问题。抛出它是因为您在迭代时修改列表。
for (ActionItemClickListener listener : actionItemClickListeners) {
isConsume = isConsume | listener.onSystemBackPressed();
}
问题是listener.onSystemBackPressed();
正在调用removeActionItemClickListener
,它会尝试更改您正在迭代过程中的actionItemClickListeners
。尝试更改您正在迭代的列表将导致ConcurrentModificationException
如何修复
在没有看到其余代码的情况下,我只能猜测如何解决此问题,但您可以使用iterator.next()
,iterator.hasNext()
和iterator.remove()
来循环并删除听众,分别。您需要传递iterator
到onSystemBackPressed()
和removeActionItemClickListener
,这有点难看,或者onSystemBackPressed()
返回一个布尔值,指示是否应该删除侦听器。
final Iterator<String> iterator = actionItemClickListeners.iterator();
while (iterator.hasNext()) {
final String listener = iterator.next();
final boolean removeListener = listener.onSystemBackPressed();
if (removeListener) {
iterator.remove();
}
isConsume = isConsume | removeListener;
}
不幸的是,看起来您正在使用onSystemBackPressed()
的返回值来表示其他内容,因此也可能无效。