【问题标题】:How to get current buildType in Android Gradle configuration如何在 Android Gradle 配置中获取当前的 buildType
【发布时间】:2014-09-09 07:41:53
【问题描述】:

我想根据当前的 buildType 在 Android Gradle 项目中动态添加依赖项。我知道我可以specify the buildType in the dependency

compile project(path: ':lib1', configuration: 'debug')

但是如何使用当前的 buildType 来指定要导入的库的哪个变体,以便调试或发布版本自动导入库的调试或发布变体?我想要的是这样的(其中 currentBuildType 是一个包含当前使用的 buildType 名称的变量):

compile project(path: ':lib1', configuration: currentBuildType)

我要导入的库项目设置了publishNonDefault true,所以所有的buildTypes都被发布了。

【问题讨论】:

标签: android android-gradle-plugin


【解决方案1】:

你可以使用

if (gradle.startParameter.taskNames.contains("assembleExample")) {
    // do stuff
}

该变量将在评估 buildConfig 块之前设置

【讨论】:

  • 您应该查看活动配置的所有任务,以确保您定义了正确的任务名称,因为它有几个变体,具体取决于您的项目设置方式。 System.out.println(gradle.startParameter.taskNames) 应该可以解决问题。然后在上面@Shooky 的示例中查找该任务。
  • @ShellDude 这为我返回了一个空列表,但 def isDebug = gradle.startParameter.taskRequests.any {it.args[0].contains("Debug")} 成功了
  • 我更喜欢这种方法...甚至可以转换为它。我想知道我们是否在这里看到了 gradle 版本或构建配置的差异。 taskRequests 和 taskNames 之间可能存在一些细微差别。
  • 但是,有一个投诉。这在 Android Studio 中不起作用,您只需重建或重新同步您的 Gradle。没有任务名称参数。
  • @JLund 更像 def isDebug = gradle.startParameter.taskRequests.any { !it.args.isEmpty() && it.args.first().contains("Debug") }
【解决方案2】:

在 Gradle 的配置阶段,我找不到获取当前构建类型的干净方法。相反,我像这样分别定义每种构建类型的依赖关系:

debugCompile project(path: ':lib1', configuration: 'debug')
releaseCompile project(path: ':lib1', configuration: 'release')

如果您有许多构建类型和许多项目依赖项,这可能会变得非常冗长,但可以添加一个函数以使依赖项成为单行。您需要将此添加到您的主要 Gradle 构建文件中:

subprojects {
    android {
        dependencies.metaClass.allCompile { dependency ->
            buildTypes.each { buildType ->
                "${buildType.name}Compile" project(path: ":${dependency.name}", configuration: buildType.name)
            }
        }
    }
}

然后您可以像这样在 Gradle 模块中添加项目依赖项:

allCompile project(':lib1')

如果您还使用构建风格,则必须调整解决方案。有关该功能的文档,请参阅此链接: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

请注意,Android 团队正在努力改进此行为: https://code.google.com/p/android/issues/detail?id=52962

【讨论】:

  • 将你的 allCompile 添加到我的 android 类工作正常,但将它添加到我的根 gradle 文件不起作用。似乎是在 android 插件之前应用的,因此它会中断:/
  • @neuron 尝试将subprojects 更改为allprojects。来自文档:'配置此项目及其每个子项目。此方法针对该项目及其子项目执行给定的闭包。'
  • 由于这对于 buildType 和 flavor 的组合是如何工作的并不明显,所以这里是解决方案:因为配置 'ReleaseCompile' 或 'DebugCompile' 不知道 gradle in在评估阶段,这些也必须动态添加: allprojects {configurations.metaClass.addFlavorConfiguration { def configName = "$flavor.name${buildType.name.capitalize()}Compile";创建(配置名称)} } } }
【解决方案3】:

添加一个依赖于每个 assembleXxx 任务和属性设置的任务

ext {
    currentConfig = ""
}
task generateConfigProperty(dependsOn: 'installDebug') {

    android.applicationVariants.all { variant ->
        variant.outputs.each { output ->

            def taskName = "taskindicate$output.name"
            task "$taskName"() << {
                project.ext.set("currentConfig", "$output.name")
            }
            output.assemble.dependsOn "taskindicate$output.name"
        }
    }

}

task getConfig(dependsOn: ['installDebug', 'generateConfigProperty']) << {
    println("My config is $currentConfig")
}

answer得到想法

【讨论】:

【解决方案4】:

这个很简单:

android {
    applicationVariants.all { variant ->
        variant.buildType.name // this is the value!
    }
}

编辑:显然在 gradle update 的某个时候,这不起作用,正如我在下面的评论中提到的那样。所以我建议检查其他选项。

【讨论】:

  • 这个循环遍历所有可用的构建类型。
  • @timkranen 如果是这样,至少循环中的最后一个是当前的。例如,如果我运行assembleDebug,它会返回“调试”,如果我运行assembleRelease,它会返回Release,它为我完成了这项工作!
  • 我一直以相同的顺序获取 BuildType 名称
  • 我收到一个错误:由于未绑定的输入和/或主题,无法应用以下模型规则:android.applicationVariants.all { ... }
  • 对我也不起作用,使用 gradle 3.2.1。它总是以相同的顺序返回构建类型。
【解决方案5】:

基于Shooky's answerJLund's comment,这对我有用。我的应用程序 build.gradle 中有这段代码接近尾声:

ext.getCurrentBuildType = {
    def isDebug = gradle.startParameter.taskRequests.any {
                            it.args.any { it.endsWith("Debug") } }
    return isDebug ? "Debug" : "Release"
}

就叫它afterEvaluate吧。示例:

afterEvaluate {
    tasks.getByName("externalNativeBuild${ext.getCurrentBuildType()}")
         .dependsOn myOtherTask
}

显然,gradle.startParameter 有大量关于当前运行的信息。看看doc

【讨论】:

  • 为了安全起见,我更喜欢it.endsWith("Debug")
  • @AlexCohn 用你的建议更新了答案。
【解决方案6】:
// declare a custom task class so you can reuse it for the different
// variants
class MyTask extends DefaultTask {
     String mVariantName;
     public void setVariantName(String variant) {mVariantName = variant;}
     public String getVariantName() { return mVariantName; }
     @TaskAction
     void action(){
        // do stuff
     }
}

// put this after your `android{}` block.
android.applicationVariants.all { variant ->
    def taskName = "myTask_$variant.name"
    task "$taskName"(type: MyTask) << {
        // you can setup this task to various info regarding
        // variant
        variantName = variant.name
    }
    variant.assemble.dependsOn (taskName)
}

有关可以从 variant 变量中提取的内容的更多详细信息,请参阅 Advance customization

现在您可以正确地将您的MyTask 连接到链中。这样做还应该干净利落地同时构建多种风格,因为它会为每个变体创建一个新的 MyTask 实例。

【讨论】:

    【解决方案7】:

    根据环境执行某段代码的思路应该是依赖注入。


    请考虑仅将以下声明用于特殊配置,因为一般情况下,代码中不应出现引用环境的条件。

    build.gradle

    android {
    
        def TRUE = "true"
        def FALSE = "false"
        def IS_DEV = "IS_DEV"
        def IS_RELEASE = "IS_RELEASE"
    
        defaultConfig {
            //...
            buildConfigField BOOLEAN, IS_DEV, FALSE
            buildConfigField BOOLEAN, IS_RELEASE, FALSE
        }
    
        buildTypes {
            debug {
                buildConfigField BOOLEAN, IS_DEV, TRUE
            }
            release {
                buildConfigField BOOLEAN, IS_RELEASE, TRUE
            }
        }
    
    }
    

    GL

    【讨论】:

      【解决方案8】:

      正在运行 Gradle 任务“assembleRelease”...

      【讨论】:

      • 请考虑向 cmets 添加链接和语句。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 2021-01-29
      • 1970-01-01
      相关资源
      最近更新 更多