内推
【长期有效】欢迎加入字节跳动我的团队:内推链接
0x1.异常概览
java.lang.StackOverflowError
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
......
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
java.util.AbstractList$SubAbstractList.iterator(AbstractList.java:301)
java.util.AbstractCollection.toArrayList(AbstractCollection.java:349)
java.util.AbstractCollection.toArray(AbstractCollection.java:339)
java.util.Collections.sort(Collections.java:1863)
此crash只出现于Android 4.4及以下系统(<=JDK 6),而5.0(>=JDK 7)及以上版本系统未出现。
0x2.分析与解决
1)由于是特定系统版本bug,故上androidxref查看对应系统版本源码。(Android 4.4)
2)再观崩溃堆栈,Collections.sort(Collections.java:1863)方法中,会调用List.toArray方法再进行排序。Collections.sort如下:
Question:直观上看代码,mNewCommingUsersTemp是一个ArrayList,ArrayList自己实现了toArray,不应该走到AbstractCollection.toArray(AbstractCollection.java:339),而且StackOverflow是由于AbstractList$SubAbstractList.listIterator(AbstractList.java:308)递归调用发生的。
Answer:所以可以肯定mNewCommingUsersTemp的引用指向应该从ArrayList对象变为了一个实现了List接口的其他对象。mNewCommingUsersTemp重新赋值就这一句:mNewCommingUsersTemp = mNewCommingUsersTemp.subList(0, NEW_COMMING_LIST_MAX_SIZE)