【问题标题】:How to get flavor name from within gradle task如何从 gradle 任务中获取风味名称
【发布时间】:2020-02-14 09:22:57
【问题描述】:

我有以下 gradle 设置:

apply plugin: 'com.android.application'

def projectName

android {
    ...
    flavorDimensions "project"
    productFlavors {
        demo {
            dimension "project"
        }
        full {
            dimension "project"
        }
    }
    ...
    applicationVariants.all { variant ->
        variant.outputs.all {
            projectName = variant.flavorName
        }
    }
}
...
task myTask(type: Copy) {
    println "flavor name is $projectName"
    ...
}
preBuild.dependsOn myTask

但是,println 没有在我的命令行/终端中显示风味名称。我错过了什么吗?我以此为参考:How to get current flavor in gradle。请注意,我必须在prebuild 之前运行我的任务。

【问题讨论】:

  • 我猜在成功评估项目(又名 afterEvaluate 方法) 后可以使用口味。
  • 因为我的任务是 preBuild 任务,所以这还不可用。你是这么说的吗?
  • 是的!可能是这样。
  • 我很快就要开始赏金了。您现在可能想添加详细的答案。 :)
  • 您找到解决方案了吗?不要浪费名声,反正我会帮你的,给我一些详细的场景。

标签: android gradle


【解决方案1】:

查看情况并找到解决方法后,看起来preBuild 无法满足您的要求。

项目容器中的 afterEvaluate 块是对您的情况有帮助的一种解决方案。

您的参考How to get current flavor in gradle 有这个answer 可以帮助找出当前产品风味 然后从applicationVariant 调用它会很有帮助。了解如何:

定义返回当前产品风味的方法

def getCurrentVariant() {
    Gradle gradle = getGradle()
    String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()

    Pattern pattern;

    if (tskReqStr.contains("assemble"))
        pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
    else
        pattern = Pattern.compile("generate(\\w+)(Release|Debug)")

    Matcher matcher = pattern.matcher(tskReqStr)

    if (matcher.find()) {
        return matcher.group(1).toLowerCase() // Changing to 2 will return build type, 1 provides product flavor
    } else {
        println "NO MATCH FOUND"
        return "";
    }
}

然后在应用级build.gradle中写入afterEvaluate 项目容器块:

project.afterEvaluate { // This container evaluates after successful sync
    android.applicationVariants.all { variant -> // We can detect all application variants
        variant.outputs.each { output -> // find out each outputs
            def taskName = "Variant -> $output.name"
            def list = output.name.tokenize('-') // Splitting output name by '-'
            println(taskName)
            if (getCurrentVariant().contains(list.get(0))) // Check if current variant matches with particular output variant
                println(getCurrentVariant())
        }
    }
}

我希望这能满足您的要求。

编辑:

不知道你是否还想要这个,但试试这个:

tasks.create('getCurrentFlavor') {
    Gradle gradle = getGradle()
    String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()

    Pattern pattern;

    if (tskReqStr.contains("assemble"))
        pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
    else
        pattern = Pattern.compile("generate(\\w+)(Release|Debug)")

    Matcher matcher = pattern.matcher(tskReqStr)

    if (matcher.find()) {
        println matcher.group(1).toLowerCase() // Changing to 2 will return build type, 1 provides product flavor
    } else {
        println "NO MATCH FOUND"
    }
}

tasks.getByName('preBuild') {
    dependsOn getCurrentFlavor
}

【讨论】:

  • 嗨。我会尽快回复您。有点忙。
  • 你好。这对我不起作用。我无法删除 preBuild.dependsOn myTask,因为我需要将其放在 preBuild 上。
  • 我刚刚开始为此提供赏金。您可能想更新您的答案。
  • 这并没有直接回答我的问题,但有解决问题的方法。给你赏金。
  • 如果我找到更可靠的东西,我会告诉你的。
【解决方案2】:

gradle 的当前风格

在为我们的一款游戏进行更新时,我需要弄清楚如何获得当前的风格并在代码中使用它。由于有很多方法可以做到这一点,我选择创建一个自定义构建配置参数并在我拥有的每个变体中设置值。

添加新的构建配置字段

首先是在您的风格中添加一个新的构建配置属性。使用buildConfigField 可以帮助我们做到这一点。因此,我定义了一个名为 VARIANTString,并根据我的口味将值设置为付费或免费。

productFlavors {
        paid {
            ...
            buildConfigField "String", "VARIANT", "\"paid\""
        }
        free {
            ...
            buildConfigField "String", "VARIANT", "\"free\""
        }
}

万一你不知道productFlavors应该放在哪里,它在你的build.gradle.的android定义中

通过这样做,您可以使用由Gradle 生成的BuildConfig 类在代码中访问该值。您可以使用相同的类来检查当前构建是否处于调试/发布模式或其他模式。

获取当前风味名称

现在,要访问新创建的属性并使用它,我会这样做:

if (BuildConfig.FLAVOR.equals("paid")){
    // do what you need to do for the paid version
} else {
    // do what you need to do for the free version
}

【讨论】:

  • 感谢您的回答。但是,我正在寻找的答案是不同的。我想从我的 gradle 任务中获取当前选择的风味名称,而不是从 Java 中获取。
  • 请关注此链接:“stackoverflow.com/a/26335681
【解决方案3】:

这就是解决我的问题的方法。

apply plugin: 'com.android.application'

def projectName

android {
    ...
    flavorDimensions "project"
    productFlavors {
        demo {
            dimension "project"
        }
        full {
            dimension "project"
        }
    }
    ...
}
...

//
// This function is what I added (from @Jeel Vankhede answer)
//
task getCurrentFlavor() {
    Gradle gradle = getGradle()
    String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()

    Pattern pattern

    if (tskReqStr.contains("assemble"))
        pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
    else
        pattern = Pattern.compile("generate(\\w+)(Release|Debug)")

    Matcher matcher = pattern.matcher(tskReqStr)

    if (matcher.find()) {
        projectName = matcher.group(1).toLowerCase() // Changing to 2 will return build type, 1 provides product flavor
    } else {
        println "NO MATCH FOUND"
    }
}

task myTask(type: Copy) {
    dependsOn getCurrentFlavor
    println "flavor name is $projectName"
    ...
}
preBuild.dependsOn myTask

基本上,我通过dependsOn getCurrentFlavor 添加了 Jeel Vankhede 的答案(如我的 gradle 文件中所述)。通过这种方式,我们可以确保在 myTask 任务中实际使用之前先填充 projectName 变量。

【讨论】:

  • 这对我不起作用,因为 gradle.getStartParameter().getTaskRequests().toString() 返回 [DefaultTaskExecutionRequest{args=[],projectPath='null'}]。知道为什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多