代码问题
4. 'getHistoricalRawPointerCoords: Invalid array index 4 for MotionEvent { action=MOVE, id[0]=0, x[0]=860.977, y[0]=1669.37, toolType[0]=2, historySize=4, eventTime=1255512616446, downTime=1255120573000, deviceId=9, source=TOUCHSCREEN | STYLUS, displayId=0, eventId=1045901346}
- MotionEvent使用相关问题
- 1.传递至其他线程处理的MotionEvent
- 2.手势检测相关传参:GestureDetector、ScaleGestureDetector
- 修复
- 使用副本
MotionEvent.obtain(event)
- 使用副本
3. 01-18 09:01:21.125 400-729/system_process E/InputDispatcher: channel '4axxxxc4 activity.XxxActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
- 内存溢出,需优化内存
2. switch-case枚举NullPointerException
- switch-case使用原理为调用枚举的ordinal方法,最终比较的是int值
- 若不能保证枚举不为null,请改为if判断
1. java.util.ConcurrentModificationException
- 循环遍历集合的过程中删除元素出现,并发修改异常
// 示例代码
for(Test test : tests) {
if (test.isDelete()) {
tests.remove(test)
}
}
原因
- 使用增强for循环遍历(底层迭代器实现)+ArrayList.remove()删除
- ArrayList的remove方法中调用fastRemove修改变量modCound,自增1
- ArrayList#Itr(继承自Iterator)的remove方法修改的是自身变量expectedModCount
- 两变量作用都是记录修改次数
- ArrayList.remove后modCound != expectedModCount会抛出ConcurrentModificationException
- modCount:记录ArrayList被修改的次数,继承自AbstractList
- expectedModCount:期望被修改次数,定义在Itr中,初始值为modCount
- 增强for遍历调用itr.next,ArrayList.remove修改modCount,但未同步修改Itr.expectedModCount,所以下次Itr.next抛异常
修复
1. 调用迭代器的remove方法,同步修改modCount与expectedModCount
for(Iterator<Test> it = tests.iterator(); it.hasNext(); ) {
Test test = it.next();
if (test.isDelete()) {
it.remove()
}
}
2. 每次删除时i自减1
for(int i = 0; i < tests.size(); i++) {
Test test = tests.get(i);
if (test.isDelete()) {
tests.remove(i);
i--;
}
}
3. 倒序记录删除下标,末尾开始删除
注意:频繁操作可使用LinkedList,线程安全可使用CopyOnWriteArrayList
附ArrayList#Itr源码
private class Itr implements Iterator<E> {
protected int limit = ArrayList.this.size;
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor < limit;
}
@SuppressWarnings("unchecked")
public E next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int i = cursor;
if (i >= limit)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
limit--;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}