能否在Android Build Gradle中非运行时检测设备ABI并控制任务执行?
问题描述
我需要在Android Build Gradle中实现以下逻辑:
- 当构建的ABI不为
arm64-v8a时,跳过指定的externalNativeBuild任务 - 仍允许不支持
arm64-v8a的设备下载应用(已配置ABI拆分规则)
当前已配置的ABI拆分规则:
splits { abi { isEnable = true reset() include("arm64-v8a", "armeabi-v7a", "x86", "x86_64") isUniversalApk = false } }
希望仅在arm64-v8a构建时执行的externalNativeBuild任务:
externalNativeBuild { cmake { path = file("src/main/cpp/CMakeLists.txt") version = "3.18.1" } }
同时想确认:是否可以在**非运行时(构建阶段)**检测当前构建目标的ABI?
解决方案
1. 构建阶段完全能检测目标ABI
当然可以在构建阶段检测当前的目标ABI,根本不用等到运行时。Gradle构建脚本可以直接获取当前构建变体的ABI信息,借此控制任务是否执行。
2. 让externalNativeBuild仅在arm64-v8a构建时运行
你可以通过变体级别的配置来实现这个逻辑,两种方法可选:
方法一:只给arm64-v8a变体配置externalNativeBuild
把原来的全局externalNativeBuild配置删掉,改为遍历所有构建变体,仅为arm64-v8a的变体启用CMake编译:
android { // 保留已有的ABI拆分配置 splits { abi { isEnable = true reset() include("arm64-v8a", "armeabi-v7a", "x86", "x86_64") isUniversalApk = false } } applicationVariants.all { variant -> variant.outputs.each { output -> def abi = output.getFilter(com.android.build.OutputFile.ABI) if (abi == "arm64-v8a") { variant.externalNativeBuild.cmake { path = file("src/main/cpp/CMakeLists.txt") version = "3.18.1" } } else { // 禁用其他ABI的CMake编译任务 variant.externalNativeBuild.cmake.enabled = false } } } }
方法二:给externalNativeBuild任务加执行条件
如果不想改动全局配置,也可以直接给所有externalNativeBuild任务添加执行条件,只有当目标ABI是arm64-v8a时才执行:
android { splits { abi { isEnable = true reset() include("arm64-v8a", "armeabi-v7a", "x86", "x86_64") isUniversalApk = false } } externalNativeBuild { cmake { path = file("src/main/cpp/CMakeLists.txt") version = "3.18.1" } } } // 过滤所有externalNativeBuild任务,设置执行条件 tasks.withType(com.android.build.gradle.tasks.ExternalNativeBuildTask) { task -> task.onlyIf { // 从变体名称中提取ABI(例如debug-arm64-v8a) def abi = task.variantName.split("-").last() abi == "arm64-v8a" } }
3. 效果验证
构建不同ABI的APK时:
- 构建arm64-v8a版本:CMake编译任务正常执行,生成对应架构的native库
- 构建其他ABI版本:CMake编译任务会被跳过,不会执行任何native代码编译
同时因为你保留了ABI拆分配置,非arm64-v8a的设备依然能下载对应架构的APK,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Denis Popkov
相关产品推荐
相关产品推荐

