Android中外部Maven库的getResource返回null问题求助
核心问题原因
Android打包工具对JNI库的处理逻辑和Java SE环境(比如Windows)不同:默认情况下,APK构建只会识别JAR中lib/[abi]/目录下的so文件,并自动打包到APK对应ABI目录;而你的库将so放在/native/android-arm64/这类非标准路径下,会被当成普通资源处理,甚至可能被构建工具过滤。同时,Android类加载器的资源访问规则和Java SE存在差异,直接用类的getResource方法访问非标准路径的so文件容易返回null。
解决步骤
1. 优先调整JAR库的JNI文件结构(若可修改库)
将so文件移动到JAR的lib/[abi]/标准目录下,比如lib/arm64-v8a/libalphaskiajni.so。这样Android构建工具会自动识别并处理,之后直接用System.loadLibrary("alphaskiajni")即可加载,无需手动通过getResource访问。
2. 无法修改库时,配置项目强制保留资源
如果不能调整JAR的结构,需要在app模块的构建脚本中添加配置,确保/native/目录下的so文件被打包进APK/AAB:
Groovy构建脚本(build.gradle)
android { // 其他已有配置... sourceSets { main { resources { include "native/**/*.so" } } } packagingOptions { pickFirst 'native/**/*.so' doNotStrip 'native/**/*.so' } }
Kotlin构建脚本(build.gradle.kts)
android { // 其他已有配置... sourceSets { main { resources { includes.add("native/**/*.so") } } } packagingOptions { pickFirst("native/**/*.so") doNotStrip("native/**/*.so") } }
3. 修正资源访问逻辑
配置完成后,调整资源访问代码,改用类加载器获取资源,避免类所在包路径的影响。同时,APK内的资源是只读的,JNI加载so需要可写入的文件路径,所以要先将so复制到应用私有目录再加载:
// 获取资源输入流 val inputStream = AlphaSkiaAndroid::class.java.classLoader.getResourceAsStream("native/android-arm64/libalphaskiajni.so") ?: throw IllegalStateException("JNI库资源未找到") // 复制到应用私有文件目录 val outputFile = File(context.filesDir, "libalphaskiajni.so") outputFile.outputStream().use { output -> inputStream.copyTo(output) } // 加载JNI库 System.load(outputFile.absolutePath)
额外验证步骤
用Android Studio的Build > Analyze APK功能打开生成的APK/AAB,确认assets/或resources/目录下存在native/android-arm64/libalphaskiajni.so文件,确保配置生效。
内容的提问来源于stack exchange,提问作者Danielku15

