You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在build.gradle中获取当前运行的Gradle assemble任务名或ABI?

解决Gradle按ABI打包时动态禁用Native Libraries构建的问题

我来帮你搞定这个需求!在Gradle中我们可以通过解析当前执行的任务名提取目标ABI,再根据这个ABI动态控制Native Libraries的编译或打包,具体实现步骤如下:

一、从任务名中提取目标ABI

Gradle提供了gradle.startParameter.taskNames来获取当前执行的所有任务列表,我们可以在项目评估阶段遍历这个列表,通过正则匹配提取出任务名里的ABI标识:

// 定义变量存储当前要构建的目标ABI
def targetAbi = null

// 项目评估完成后解析任务名(此时所有任务已初始化)
gradle.projectsEvaluated {
    gradle.startParameter.taskNames.each { taskName ->
        // 匹配assemble<ABI><BuildType>格式的任务,比如assembleMipsDebug、assembleArmeabi-v7aRelease
        def abiMatcher = taskName =~ /assemble([A-Za-z\-]+)(Debug|Release)/
        if (abiMatcher.matches()) {
            // 提取ABI并转为小写格式(确保和native库目录名一致)
            targetAbi = abiMatcher[0][1].toLowerCase()
            println "当前目标ABI: $targetAbi"
        }
    }
}

这段代码会自动识别类似assembleMipsDebug的任务,把mips提取出来存到targetAbi变量里,带连字符的ABI(比如armeabi-v7a)也能正常匹配。

二、根据目标ABI动态控制Native Libraries构建

接下来我们可以根据targetAbi的值,调整Native Libraries的编译或打包配置,分两种场景说明:

场景1:动态控制CMake/NDK-Build的编译过程

如果你用CMake或NDK-Build编译Native代码,可以把targetAbi作为参数传递给构建脚本,在脚本中判断是否编译指定库:

用CMake的例子

在build.gradle的externalNativeBuild中传递参数:

android {
    // 先配置ABI拆分(确保只生成对应ABI的APK)
    splits {
        abi {
            enable true
            reset()
            include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips'
            universalApk false
        }
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
            // 把目标ABI传递给CMake
            arguments "-DTARGET_ABI=$targetAbi"
        }
    }
}

然后在CMakeLists.txt中判断是否编译指定库:

# 只有当目标ABI不是mips时,才编译foo库
if(NOT TARGET_ABI STREQUAL "mips")
    add_library(foo SHARED src/main/cpp/foo.cpp)
    # 其他链接、配置逻辑...
endif()

用NDK-Build的例子

在build.gradle中传递参数:

android {
    splits {
        abi {
            enable true
            reset()
            include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips'
            universalApk false
        }
    }

    externalNativeBuild {
        ndkBuild {
            path "Android.mk"
            arguments "TARGET_ABI=$targetAbi"
        }
    }
}

在Android.mk中控制模块编译:

# 如果是mips架构,跳过bar模块的编译
ifeq ($(TARGET_ABI),mips)
    LOCAL_MODULES_TO_SKIP := bar
else
    # 正常编译所有模块
    include $(call all-subdir-makefiles)
endif

场景2:过滤已编译的Native库(适用于预编译库)

如果你用的是预编译好的Native库,可以直接在Gradle中过滤要打包的库目录:

android {
    sourceSets {
        main {
            jniLibs.srcDirs = ["src/main/jniLibs"]
            // 根据目标ABI过滤库目录
            if (targetAbi == 'mips') {
                // 只保留mips的库,排除其他架构
                jniLibs.exclude '**/armeabi-v7a/**', '**/arm64-v8a/**', '**/x86/**', '**/x86_64/**'
            } else {
                // 排除mips的库
                jniLibs.exclude '**/mips/**'
            }
        }
    }
}

三、注意事项

  • 必须在gradle.projectsEvaluated阶段解析任务名:这个阶段Gradle已经完成了所有任务的初始化,能正确获取到执行的任务列表;如果在更早的阶段(比如项目刚初始化时),任务列表可能还未生成。
  • 多任务执行的情况:如果同时执行多个assemble任务(比如assembleMipsDebug和assembleArmeabiDebug),targetAbi会被最后一个匹配的任务覆盖。如果需要支持多任务,你可以调整逻辑,把所有匹配到的ABI都收集起来处理。

内容的提问来源于stack exchange,提问作者Poka Yoke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:18:50