Android Gradle如何按指定目录结构引入.so共享对象(适配产品风味)
针对你遇到的Android Gradle打包时无法保留.so文件子目录结构、同时适配产品风味的问题,我整理了一套可行的Gradle脚本方案,完美适配你的演示项目需求:
问题回顾
默认通过jniLibs.srcDirs引入.so文件会生成扁平结构,而你需要将插件类.so按armeabi-v7a/plugins/test1/test1.so这类子目录结构打包进APK;尝试谷歌Issue里的方案后,仅生成了.so.recipe文件,实际.so被过滤,且不想修改System.loadLibrary逻辑,希望用Gradle层面的简便方案解决。
解决方案
下面的Gradle脚本通过自定义打包任务,将带目录结构的插件.so文件打包成Jar再引入依赖,确保目录结构被完整保留并正确打包进APK,同时适配产品风味:
dependencies { implementation 'com.android.support.constraint:constraint-layout:1.0.2' // 引入自定义打包的包含插件.so的Jar文件 compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar') } // 自定义任务:将带子目录结构的插件.so打包为Jar task nativeLibsToJar(type: Zip) { destinationDir file("$buildDir/native-libs") baseName 'native-libs' extension 'jar' // 读取对应产品风味+构建配置下的插件目录内所有.so相关文件 from fileTree(dir: getCurrentConfigAbiDir() + "/plugins", include: '**/*.so*') // 指定Jar内的路径,对应APK最终的/lib/[ABI]/plugins/...结构 into "/lib/" + getCurrentAbiFolder() + "/plugins" } // 让Java编译任务依赖自定义打包任务,确保Jar在编译前生成 tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn(nativeLibsToJar) } // -------------------------- 辅助工具函数 -------------------------- // 获取当前产品风味对应的ABI文件夹名称(如armeabi-v7a) String getCurrentAbiFolder() { String[] props = getCommandLineArgs() if( props.length != 2 ) return "" String platform = props[0] String config = props[1] String targetAbi = "" android.productFlavors.all { flavour -> if( flavour.name.toLowerCase() == platform.toLowerCase() ) targetAbi = flavour.ndk.abiFilters.first().toLowerCase() } return targetAbi } // 获取当前产品风味+构建配置对应的.so文件根目录 String getCurrentConfigAbiDir() { String targetDir = "DoesNotExists" String[] props = getCommandLineArgs() if( props.length != 2 ) return targetDir String platform = props[0] String config = props[1] android.productFlavors.all { flavour -> if( flavour.name.toLowerCase() == platform.toLowerCase() ) targetDir = "bin/" + config + "/" + flavour.ndk.abiFilters.first().toLowerCase() } return targetDir }
关键逻辑说明
- 自定义Zip任务:
nativeLibsToJar会扫描你指定的bin/[构建配置]/[ABI]/plugins目录下的所有.so文件,按/lib/[ABI]/plugins/的层级结构打包进Jar,Gradle处理依赖时会完整保留这个结构,最终同步到APK的对应路径中。 - 依赖绑定:将Java编译任务与自定义打包任务关联,确保在代码编译前就生成好包含插件.so的Jar,避免出现依赖缺失问题。
- 产品风味适配:两个辅助函数会解析命令行传入的产品风味和构建配置参数,自动匹配对应的ABI目录,完美适配多风味项目的打包需求。
使用注意事项
- 确保你的项目目录结构符合预期:比如
bin\Debug\armeabi-v7a\plugins\test1\test1.so这类路径必须正确存在。 - 执行打包命令时需指定产品风味和构建配置,例如
./gradlew assembleMyFlavorDebug,辅助函数会自动解析对应的ABI目录。
内容的提问来源于stack exchange,提问作者TarmoPikaro
相关产品推荐
相关产品推荐

