如何在分级中获得流行风味

我的应用程序有两种产品风格:

productFlavors {
europe {
buildConfigField("Boolean", "BEACON_ENABLED", "false")
}


usa {
buildConfigField("Boolean", "BEACON_ENABLED", "true")
}
}

现在,我想在一个任务中获取当前风格的名称(我在 Android Studio 中选择的名称)来更改路径:

task copyJar(type: Copy) {
from('build/intermediates/bundles/' + FLAVOR_NAME + '/release/')
}

如何在 Gradle 取得 FLAVOR _ NAME?

谢谢

72058 次浏览

这是我以前用过的。我希望它仍然与最新的 Gradle 插件工作。我基本上遍历了所有的风味,并设置了一个新的输出文件,它看起来类似于您试图实现的。

applicationVariants.all { com.android.build.gradle.api.ApplicationVariant variant ->
for (flavor in variant.productFlavors) {
variant.outputs[0].outputFile = file("$project.buildDir/${YourNewPath}/${YourNewApkName}.apk")
}
}

我的解决方案是解析梯度输入参数。

Gradle gradle = getGradle()


Pattern pattern = Pattern.compile(":assemble(.*?)(Release|Debug)");
Matcher matcher = pattern.matcher(gradle.getStartParameter().getTaskRequests().toString());
println(matcher.group(1))

如何得到当前的口味名称

我已经开发了以下函数,返回的正是 现在的口味名称:

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


Pattern pattern


if( tskReqStr.contains( "assemble" ) ) // to run ./gradlew assembleRelease to build APK
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
else if( tskReqStr.contains( "bundle" ) ) // to run ./gradlew bundleRelease to build .aab
pattern = Pattern.compile("bundle(\\w+)(Release|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")


Matcher matcher = pattern.matcher( tskReqStr )


if( matcher.find() )
return matcher.group(1).toLowerCase()
else
{
println "NO MATCH FOUND"
return ""
}
}

你也需要

import java.util.regex.Matcher
import java.util.regex.Pattern

或者你的剧本。 在 Android Studio 中,这通过“ Make Project”或“ Debug App”按钮进行编译。

如何获得当前的构建变量

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(2).toLowerCase()
}else{
println "NO MATCH FOUND"
return ""
}
}

如何获得当前风味应用 ID

一个类似的问题可能是: 如何得到 ApplicationId? 此外,在这种情况下,没有直接的方法来获得当前的风味 ApplicationId。然后,我使用上述定义的 GetCurrentFlavor函数开发了一个 gradle 函数,如下所示:

def getCurrentApplicationId() {
def currFlavor = getCurrentFlavor()


def outStr = ''
android.productFlavors.all{ flavor ->


if( flavor.name==currFlavor )
outStr=flavor.applicationId
}


return outStr
}

好了。

你应该使用这个,${variant.productFlavors[0].name},它会得到 productFlavors IDE 和命令行。

在等级同步完成后,从. iml 文件中获取 SELECTED _ BUILD _ VARIANT 您可以使用 xml 解析器加载它,也可以使用不太理想的方法加载它,但是使用正则表达式来查找它可能会更快一些。

<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="your_build_flavorDebug" />
...

(未经测试,类似这样的东西:)

/(?=<name="SELECTED_BUILD_VARIANT".*value=")[^"]?/

你可以使用 gradle.startParameter.taskNames[0]

我稍微改变了 Poiana Apuana的答案,因为我的口味有一些大写字母。

原因
gradle.getStartParameter().getTaskRequests().toString()包含您当前的风味名称,但第一个字符是大写。
但是,通常风味的名字都是以小写字母开头的,所以我不得不把第一个字符改成小写字母。

def getCurrentFlavor() {
Gradle gradle = getGradle()
String taskReqStr = gradle.getStartParameter().getTaskRequests().toString()
Pattern pattern
if (taskReqStr.contains("assemble")) {
pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
} else {
pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
}
Matcher matcher = pattern.matcher(taskReqStr)
if (matcher.find()) {
String flavor = matcher.group(1)
// This makes first character to lowercase.
char[] c = flavor.toCharArray()
c[0] = Character.toLowerCase(c[0])
flavor = new String(c)
println "getCurrentFlavor:" + flavor
return flavor
} else {
println "getCurrentFlavor:cannot_find_current_flavor"
return ""
}
}

我用这个

${variant.getFlavorName()}.apk

格式化文件名输出

用途:

${variant.baseName}.apk"

此返回当前风味名称

完整答案

android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "${variant.baseName}.apk"
}
}

如何从 prebuild任务获得风味名称或构建变体?这解决了我的问题。我在任务的 dependOn中加入了 getCurrentFlavor()getCurrentVariant()(来自@Poiana Apuana 答案) ,如下所示:

task getCurrentFlavor() {
// paste Poiana Apuana's answer
}


// OR
//task getCurrentVariant() {
//  // paste Poiana Apuana's answer
//}


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

检查原始问题 给你

你可以检查一下味道,假设你的分级是

productFlavors {
test{
...
buildConfigField "String", "VARIANT", "\"test\""
}
prod{
...
buildConfigField "String", "VARIANT", "\"prod\""
}
}

现在通过使用下面的代码你可以检查你的味道。

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

只需在 build.gradle(应用程序级别)中添加以下内容

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


Pattern pattern;
if( tskReqStr.contains( "assemble" ))
pattern = Pattern.compile("assemble(\\w+)(Release|Staging|Debug)")
else
pattern = Pattern.compile("generate(\\w+)(Release|Staging|Debug)")
Matcher matcher = pattern.matcher( tskReqStr )
if( matcher.find() ) {
def value = matcher.group(1).toLowerCase()
return value
} else {
return "";
}
}

android标签内,

android {
// android tag starts
defaultConfig {
- - - - - - - -
- - - - - - - -
}
- - - - - - - -
- - - - - - - -
 

def flavourName = getCurrentFlavour()
if (flavourName == "Dev") {
println("This is Dev")
} else if (flavourName == "Staging") {
println("This is Staging")
} else if (flavourName == "Production") {
println("This is Production")
} else {
println("NA")
}
// android tag ends
}

现在 同步与构建你的项目。

我需要结合前面提到的一些片段才能让这个工作正常进行。

我对最初问题的完整回答是这样的:

android {
...
applicationVariants.all { variant ->
task "${variant.getName()}CopyJar"(type: Copy) {
from("build/intermediates/bundles/${variant.getFlavorName()}/release/")
}
}
}

这将为每个变体创建一个 <variant>CopyJar任务,然后可以手动运行该任务。