Android Collection.sort根据Android API版本不一致地崩溃

时间:2019-07-11 21:22:11

标签: java android

一个有趣的错误,基本上,如果您的Android代码中包含以下代码行,则该错误会在Android API 21上崩溃,但在API 28上有效

Collections.sort(Collections.singletonList(“1”));


java.lang.UnsupportedOperationException
at java.util.AbstractList.set(AbstractList.java:681)
at java.util.AbstractList$FullListIterator.set(AbstractList.java:143)
at java.util.Collections.sort(Collections.java:1869)
at com.davidcorrado.collectionssort.CollectionJavaUnitTest2.Collection_Sort_Immutable(CollectionJavaUnitTest2.java:16)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

我了解为什么它会崩溃,因为它不允许Collection.sort中的不可变对象,但是我真的不理解不一致之处。

我有以下代码示例: https://github.com/DavidCorrado/CollectionSortCrash/blob/master/app/src/androidTest/java/com/davidcorrado/collectionssort/CollectionJavaUnitTest2.java

因此,如果您运行上述针对API 21仿真器的测试会崩溃,但在API 28仿真器上它将正常工作。这也适用于真实设备。

所以我有2个问题

1)我不知道的这些设备的不同之处导致了这一点。

2)有没有一种方法可以解决此错误。我有一个成功的代码示例。

1 个答案:

答案 0 :(得分:1)

它可与API 28一起使用,因为替换了sort的实现,并且新版本具有优化功能,如果使用list.size() <= 1,则跳过了排序。

跳过排序时,它不会调用list.set(),因此永远不会触发不可变列表的UnsupportedOperationException

较旧的API级别没有这种优化。