使用commons-io:commons-io 2.5之后的版本导致Android 8以下设备应用崩溃的解决方法求助
commons-io:commons-io 2.5之后的版本导致Android 8以下设备应用崩溃的解决方法求助
我之前升级commons-io版本时也踩过一模一样的坑,折腾了好一阵才摸清楚来龙去脉,给你几个实用的解决思路:
先搞懂问题根源
从commons-io 2.6版本开始,官方内部大量使用了Java 7引入的NIO.2 API(就是你报错里的java.nio.file.OpenOption),而Android 8.0(API 26)以下的系统原生根本没有这些类的实现。你代码里调用的IOUtils.toByteArray(stream),在高版本commons-io里已经依赖了这些新API,所以低版本Android设备跑起来就会找不到类直接崩溃。
最直接的解决:把Desugaring配置改对!
你现在的配置里coreLibraryDesugaringEnabled = false是关闭了desugaring功能,这完全搞反了!Desugaring就是用来给低版本Android补全Java 8+ API支持的,必须把它打开才能解决这个问题。具体操作:
- 打开你app模块的
build.gradle(或者build.gradle.kts) - 在
android块的compileOptions里,把desugaring开关打开,同时指定Java版本为1.8:compileOptions { coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } - 在
dependencies块里,确保desugar的依赖正确引入,建议用较新的稳定版(你之前的2.1.5有点老,可能对某些API支持不足):dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.2.4' implementation 'commons-io:commons-io:2.20' // 其他项目依赖... } - 同步Gradle,清理下项目缓存(File -> Invalidate Caches / Restart),重新编译运行试试。
备选方案:如果不想开Desugaring
要是你因为某些原因不想启用desugaring,也可以试试这两个办法:
- 暂时回退到commons-io 2.5版本,这个版本还没引入NIO.2相关代码,对低版本Android兼容性更好
- 自己实现一个简单的流转字节数组的方法,替代
IOUtils.toByteArray,比如:
这个方法完全不依赖commons-io的新API,在低版本Android上也能正常跑。public static byte[] streamToByteArray(InputStream input) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[1024]; while ((nRead = input.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); return buffer.toByteArray(); }
额外检查点
- 要是开了desugaring还是崩溃,去看看依赖树有没有冲突:用
./gradlew app:dependencies命令检查,确认有没有其他库偷偷引入了旧版本的commons-io,导致代码混合调用了新旧版本的API - 确保你的
compileSdkVersion至少在26以上,虽然不是直接原因,但高版本的编译SDK能更好地配合desugaring工作
内容来源于stack exchange




