Android7及以下使用commons-io 2.11.0遇NoSuchMethodError崩溃求助
解决Android 7及以下系统中commons-io引发的NoSuchMethodError异常
问题背景
项目引入commons-io 2.11.0依赖:
implementation 'commons-io:commons-io:2.11.0'
在Android 7.0及以下系统中出现崩溃,Crash日志显示:
Fatal Exception: java.lang.NoSuchMethodError: No static method withInitial(Ljava/util/function/Supplier;)Ljava/lang/ThreadLocal; in class Ljava/lang/ThreadLocal; or its super classes (declaration of 'java.lang.ThreadLocal' appears in /system/framework/core-oj.jar) at org.apache.commons.io.IOUtils.<clinit>(IOUtils.java:183) at org.apache.commons.io.IOUtils.closeQuietly(IOUtils.java:534)
已配置Java 8兼容性,但问题依然存在:
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } }
原因分析
ThreadLocal.withInitial()是Java 8新增的静态方法,但Android 7.0(API 24)及以下的系统内置库并未实现该方法。- commons-io 2.11.0版本的
IOUtils类在静态初始化阶段调用了该方法,导致低版本系统加载类时直接抛出异常。 - 仅配置
compileOptions的Java 8兼容不足以处理第三方库中的Java 8核心API调用,需要额外的核心库脱糖(Desugar)支持,或者使用兼容低版本的依赖版本。
解决方案
方案1:降级commons-io到兼容低版本Android的版本
选择不依赖ThreadLocal.withInitial()的commons-io版本,比如2.6版本,该版本的IOUtils未使用该Java 8方法,可直接在低版本Android系统运行:
implementation 'commons-io:commons-io:2.6'
方案2:启用完整的核心库脱糖(Desugar)支持
若需要保留commons-io 2.11.0的新特性,可通过配置Desugar工具将第三方库中的Java 8核心API转译为低版本Android支持的实现:
- 在
dependencies块中添加Desugar依赖:
dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' }
- 在
android块中启用核心库脱糖:
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 coreLibraryDesugaringEnabled true } kotlinOptions { jvmTarget = "1.8" } }
内容的提问来源于stack exchange,提问作者Ali Asjad
相关产品推荐
相关产品推荐

