旧版Android设备能否使用高版本commons-io?问题及解决尝试
Apache Commons IO旧版Android兼容问题及解决尝试
我一直使用Apache Commons IO 2.5版本:
implementation 'commons-io:commons-io:2.5'
这是因为从2.6版本开始,该库会导致Android 4.2及其他旧版设备上的应用崩溃。
之后我尝试升级到最新的2.13.0版本:
implementation 'commons-io:commons-io:2.13.0'
但在Android 5.1和7.1设备上依然出现崩溃,报错始终为NoClassDefFoundError:
java.lang.NoClassDefFoundError: org.apache.commons.io.IOUtils at org.apache.commons.io.IOUtils.toString(IOUtils.java:3104)
引发问题的代码是:
IOUtils.toString(inputStream, StandardCharsets.UTF_8);
这段代码在Android 9、10等新版本系统上运行正常。
更新(2024-04-25)
启用desugaring后,之前的NoClassDefFoundError问题得到解决,但又出现了新的崩溃:
java.lang.NoClassDefFoundError: Failed resolution of: [Ljava/nio/file/OpenOption; at org.apache.commons.io.file.PathUtils.<clinit>(PathUtils.java:151) at org.apache.commons.io.build.AbstractStreamBuilder.<clinit>(AbstractStreamBuilder.java:41) at org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream.builder(UnsynchronizedByteArrayOutputStream.java:83) at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:2644)
目前只能退回使用2.5版本,求可行的解决办法。
可行解决办法
使用Android专用分支
尝试引入专为Android优化的commons-io-android分支,它移除了旧Android不支持的Java NIO文件API依赖,适配性更好:implementation 'commons-io:commons-io-android:2.13.0'自定义轻量工具类
如果仅用到IOUtils.toString这类基础功能,可以自己实现工具类替代,避免引入整个库:public class CustomIOUtils { public static String toString(InputStream inputStream, Charset charset) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset)); String line; while ((line = reader.readLine()) != null) { sb.append(line).append('\n'); } if (sb.length() > 0) { sb.setLength(sb.length() - 1); } reader.close(); return sb.toString(); } }尝试2.8.0过渡版本
Commons IO 2.8.0是最后一个未大量引入Java NIO文件API的版本,修复了2.5的部分bug,同时兼容旧Android:implementation 'commons-io:commons-io:2.8.0'优化ProGuard规则
若坚持使用高版本,可添加ProGuard规则确保必要类不被混淆或移除:-keep class org.apache.commons.io.** { *; } -keep interface org.apache.commons.io.** { *; }同时确保desugaring配置正确,开启Java 8+兼容支持。
内容的提问来源于stack exchange,提问作者Hong
相关产品推荐
相关产品推荐

