初探NDK高版本Gradle so导入异常的来龙去脉
2023-11-11 14:24:24
NDK Gradle 高版本:解决 SO 文件导入异常的完整指南
背景
在 Android 开发中,引入本地库文件(.so 文件)需要利用 NDK(Native Development Kit)和 Gradle。然而,在高版本的 Gradle 中,使用 NDK 导入 so 文件时可能会遭遇异常。本文将深入探讨异常的根源、原因并提供全面的解决方案。
异常信息
* What went wrong:
Execution failed for task ':app:mergeNativeLibs'.
> Duplicate files copied in APK META-INF/lib/arm64-v8a/:
- /Users/username/AndroidStudioProjects/app/build/intermediates/ndkBuild/release/libs/arm64-v8a/libnative-lib.so
- /Users/username/AndroidStudioProjects/app/build/intermediates/ndkBuild/debug/libs/arm64-v8a/libnative-lib.so
异常根源
异常的根源在于高版本的 Gradle 工具会自动导入默认 so 库路径下的所有文件,包括在 build/intermediates/ndkBuild
目录下的文件。
原因
旧的导入方式仅在 build/intermediates/ndkBuild/release/libs
和 build/intermediates/ndkBuild/debug/libs
目录下查找并导入 so 文件。然而,高版本的 Gradle 工具扩展了搜索范围,包括上述目录以及其他可能包含 so 文件的目录。
解决方案
1. 修改 Gradle 配置
在 build.gradle
文件中,找到 android
块并添加以下配置:
android {
...
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
...
}
这将指示 Gradle 仅在 src/main/jni/Android.mk
文件指定的路径下查找并导入 so 文件。
2. 使用 SO 映射
在 build.gradle
文件中,找到 android
块并添加以下配置:
android {
...
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
packagingOptions {
pickFirst '**/*.so'
}
...
}
这将指示 Gradle 仅导入第一个找到的 so 文件,从而避免重复导入。
3. 使用 SO 过滤
在 build.gradle
文件中,找到 android
块并添加以下配置:
android {
...
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
packagingOptions {
excludes '**/arm64-v8a/libnative-lib.so'
}
...
}
这将指示 Gradle 排除指定的 so 文件,从而避免重复导入。
结论
通过采用上述解决方案,开发人员可以解决 NDK 高版本 Gradle so 导入异常的问题。了解异常的根源和原因对于有效地解决此类问题至关重要。
常见问题解答
1. 为什么会发生此异常?
高版本的 Gradle 工具会自动导入默认 so 库路径下的所有文件,导致重复导入和异常。
2. 异常的根源是什么?
Gradle 工具的搜索范围扩展到了默认 so 库路径下的所有目录。
3. 有哪些解决方案可以解决此问题?
修改 Gradle 配置、使用 so 映射或使用 so 过滤都可以有效解决问题。
4. 如何修改 Gradle 配置以解决此问题?
在 build.gradle
文件中,添加 externalNativeBuild
和 ndkBuild
配置,并指定 so 文件的路径。
5. 如何使用 so 映射或 so 过滤来解决此问题?
通过在 build.gradle
文件中的 packagingOptions
块中添加 pickFirst
或 excludes
配置,可以使用 so 映射或 so 过滤。