简体   繁体   English

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

[英]Android Collection.sort inconsistently crashes based on Android API Version

An interesting bug that essentially if you have this line of code in your Android code it crashes on Android API 21 but works on API 28 一个有趣的错误,基本上,如果您的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)

I understand why it crashes as it does not allow immutable objects in Collection.sort but I really do not understand the inconsistency. 我理解为什么它崩溃,因为它不允许Collection.sort中的不可变对象,但是我真的不理解不一致的地方。

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

So if you run the above test targeting API 21 emulator it crashes but on API 28 emulator it works. 因此,如果您运行上述针对API 21仿真器的测试会崩溃,但在API 28仿真器上它将正常工作。 This also applies to real devices. 这也适用于真实设备。

So I have 2 questions 所以我有两个问题

1) What in different in these devices that I do not know about that causes this. 1)我不知道这些设备的不同之处导致了这一点。

2) Is there a way to get this error in robo electric. 2)有没有办法解决此错误的机器人。 I have a code example that succeeds. 我有一个成功的代码示例。

It works with API 28 because the implementation of sort was replaced, and the new version has optimization that simply skips the sorting if list.size() <= 1 . 它可以与API 28一起使用,因为替换了sort的实现,并且新版本具有优化,如果list.size() <= 1则跳过了排序。

When sorting is skipped, it doesn't calls list.set() , and hence never triggers the UnsupportedOperationException of an immutable list. 跳过排序时,它不会调用list.set() ,因此永远不会触发不可变列表的UnsupportedOperationException

Older API levels don't have that optimization. 较旧的API级别没有这种优化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM