如何在 gradle 中仅将插件应用于一种口味?
How to apply plugin to only one flavor in gradle?
我有一个多风格、多构建类型的 android 项目,我想集成 NewRelic 插件。但是我只能为其中一位客户申请,因此只能为一种产品口味申请。
NewRelic 使用检测,如果我在那里应用插件,插件会生成其他风格的代码,这是我们不允许的。
所以我的问题是:如何使用 gradle 文件中的 apply plugin: something
命令仅应用于我的一种口味?
我找到了解决方案,但目前还不是最好的。
所以我不再确定,我最初想做的事情是否可行。
gradle 文件评估和选择正确的风格和构建类型是在 gradle 构建的不同阶段,所以我所做的是:
我使用命令行中的构建参数。当该参数为真时,我应用该插件,当它甚至不存在时,我也应用它(对于 IDE 构建)。
我使用 Jenkins,所以我可以在构建作业中写入该参数。
build.gradle 文件:
// First we have to attach a task to the project, which will be running first
gradle.projectsEvaluated {
preBuild.dependsOn(applyNewRelicByProperty)
}
// Then check on the parameter, which comes from the command line
task applyNewRelicByProperty {
if(!project.hasProperty('compileNewRelic')) {
// NewRelic on: 'compileNewRelic' property not set, so running from IDE.
apply plugin: 'newrelic'
} else if(project.hasProperty('compileNewRelic') && project.getProperties().get('compileNewRelic').equals('true')) {
// NewRelic on: 'compileNewRelic' property is set and it is 'true'.
apply plugin: 'newrelic'
} else {
// NewRelic off
println("No NewRelic")
}
}
并且您必须 运行 gradle 通过以下方式构建:
assembleYourApp -PcompileNewRelic=true
- 定义变量 -
def fl
在你的 Flavors 中初始化变量(and/or 构建)
productFlavors {
freeFlavour {
(...)
fl = "free"
}
paidFlavour {
(...)
fl = "paid"
}
}
使用 if 语句 -
if (fl == "free") {
apply plugin: something
}
使用此代码:
if (!getGradle().getStartParameter().getTaskRequests()
.toString().contains("Develop")){
apply plugin: 'com.google.gms.google-services'
}
getGradle().getStartParameter().getTaskRequests().toString()
returns 像 [DefaultTaskExecutionRequest{args=[:app:generateDevelopDebugSources],projectPath='null'}]
这样的东西,如评论中所述 Develop
必须以大写字母开头。
尝试了不同的解决方案,但 none 对我有用。这是我想出的,据我测试似乎有效:
build.gradle
productFlavors {
someFlavorWithGoogleGcm {
dimension "type"
applicationId "com.example.withGcm"
ext.useGoogleGcm = true
}
someFlavorWithoutGoogleGcm {
dimension "type"
applicationId "com.example.withoutGcm"
}
}
在配置之外,在 build.gradle
文件内:
android.productFlavors.each { flavor ->
if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase().contains(flavor.name) && flavor.ext.useGoogleGcm) {
println("Building flavor with Google GCM [${flavor.name}] - applying plugin")
apply plugin: 'com.google.gms.google-services'
}
}
我只是在应用级别 build.gradle 的 flavor 中使用了 apply plugin: 'com.google.gms.google-services'
,它工作得很好。
productFlavors {
..... your other flavors ....
yourFlv {
....
....
apply plugin: 'com.google.gms.google-services'
}
}
不需要额外的步骤。
对于 Google 服务 Gradle 插件,以下工作。
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
tasks.matching { it.name.contains("GoogleServices") && !it.name.contains(yourFlavorName) }*.enabled = false
}
其中 yourFlavorName
是一个大写的字符串,其中包含您必须应用插件的风味名称;所有其他口味不使用该插件。
请注意,该插件仍适用于其他口味;此解决方案只是为他们禁用 *GoogleServices*
任务。这假设 Google 服务 Gradle 插件仅通过添加包含子字符串 "GoogleServices"
的任务来应用更改,这在将来可能不起作用。
要检查这是否有效,您可以检查依赖项,例如像这样:
./gradlew app:dependencyInsight --configuration yourFlavorNameDebugCompileClasspath --dependency google | grep -i services
这应该会显示 yourFlavorName
的一些依赖关系,但不会显示其他风味名称的依赖关系:
./gradlew app:dependencyInsight --configuration otherFlavorNameDebugCompileClasspath --dependency google | grep -i services
升级到 Gradle 4.2 后,Tarps 的方法不再有效,所以我最终将它与 Erik 的答案结合起来。
为 build.gradle
中的每种口味设置 ext.useGoogleGcm
:
productFlavors {
a {
...
ext.useGoogleGcm = true
}
b {
...
ext.useGoogleGcm = false
}
}
然后在文件底部:
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
android.productFlavors.each { flavor ->
tasks.matching {
it.name.contains('GoogleServices') && it.name.contains(flavor.name.capitalize())
}*.enabled = flavor.ext.useGoogleGcm
}
}
在您的 assembleRelease
任务的输出中,您应该会看到名称中带有“GoogleServices”的任务对于正确的任务有 运行,对于错误的任务则跳过。如果您的构建抱怨 toCapitalize
,您可以在 it.name
和 flavor.name
上使用 toLowerCase
。
我有一个多风格、多构建类型的 android 项目,我想集成 NewRelic 插件。但是我只能为其中一位客户申请,因此只能为一种产品口味申请。
NewRelic 使用检测,如果我在那里应用插件,插件会生成其他风格的代码,这是我们不允许的。
所以我的问题是:如何使用 gradle 文件中的 apply plugin: something
命令仅应用于我的一种口味?
我找到了解决方案,但目前还不是最好的。 所以我不再确定,我最初想做的事情是否可行。 gradle 文件评估和选择正确的风格和构建类型是在 gradle 构建的不同阶段,所以我所做的是:
我使用命令行中的构建参数。当该参数为真时,我应用该插件,当它甚至不存在时,我也应用它(对于 IDE 构建)。 我使用 Jenkins,所以我可以在构建作业中写入该参数。
build.gradle 文件:
// First we have to attach a task to the project, which will be running first
gradle.projectsEvaluated {
preBuild.dependsOn(applyNewRelicByProperty)
}
// Then check on the parameter, which comes from the command line
task applyNewRelicByProperty {
if(!project.hasProperty('compileNewRelic')) {
// NewRelic on: 'compileNewRelic' property not set, so running from IDE.
apply plugin: 'newrelic'
} else if(project.hasProperty('compileNewRelic') && project.getProperties().get('compileNewRelic').equals('true')) {
// NewRelic on: 'compileNewRelic' property is set and it is 'true'.
apply plugin: 'newrelic'
} else {
// NewRelic off
println("No NewRelic")
}
}
并且您必须 运行 gradle 通过以下方式构建:
assembleYourApp -PcompileNewRelic=true
- 定义变量 -
def fl
在你的 Flavors 中初始化变量(and/or 构建)
productFlavors { freeFlavour { (...) fl = "free" } paidFlavour { (...) fl = "paid" } }
使用 if 语句 -
if (fl == "free") { apply plugin: something }
使用此代码:
if (!getGradle().getStartParameter().getTaskRequests()
.toString().contains("Develop")){
apply plugin: 'com.google.gms.google-services'
}
getGradle().getStartParameter().getTaskRequests().toString()
returns 像 [DefaultTaskExecutionRequest{args=[:app:generateDevelopDebugSources],projectPath='null'}]
这样的东西,如评论中所述 Develop
必须以大写字母开头。
尝试了不同的解决方案,但 none 对我有用。这是我想出的,据我测试似乎有效:
build.gradle
productFlavors {
someFlavorWithGoogleGcm {
dimension "type"
applicationId "com.example.withGcm"
ext.useGoogleGcm = true
}
someFlavorWithoutGoogleGcm {
dimension "type"
applicationId "com.example.withoutGcm"
}
}
在配置之外,在 build.gradle
文件内:
android.productFlavors.each { flavor ->
if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase().contains(flavor.name) && flavor.ext.useGoogleGcm) {
println("Building flavor with Google GCM [${flavor.name}] - applying plugin")
apply plugin: 'com.google.gms.google-services'
}
}
我只是在应用级别 build.gradle 的 flavor 中使用了 apply plugin: 'com.google.gms.google-services'
,它工作得很好。
productFlavors {
..... your other flavors ....
yourFlv {
....
....
apply plugin: 'com.google.gms.google-services'
}
}
不需要额外的步骤。
对于 Google 服务 Gradle 插件,以下工作。
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
tasks.matching { it.name.contains("GoogleServices") && !it.name.contains(yourFlavorName) }*.enabled = false
}
其中 yourFlavorName
是一个大写的字符串,其中包含您必须应用插件的风味名称;所有其他口味不使用该插件。
请注意,该插件仍适用于其他口味;此解决方案只是为他们禁用 *GoogleServices*
任务。这假设 Google 服务 Gradle 插件仅通过添加包含子字符串 "GoogleServices"
的任务来应用更改,这在将来可能不起作用。
要检查这是否有效,您可以检查依赖项,例如像这样:
./gradlew app:dependencyInsight --configuration yourFlavorNameDebugCompileClasspath --dependency google | grep -i services
这应该会显示 yourFlavorName
的一些依赖关系,但不会显示其他风味名称的依赖关系:
./gradlew app:dependencyInsight --configuration otherFlavorNameDebugCompileClasspath --dependency google | grep -i services
升级到 Gradle 4.2 后,Tarps 的方法不再有效,所以我最终将它与 Erik 的答案结合起来。
为 build.gradle
中的每种口味设置 ext.useGoogleGcm
:
productFlavors {
a {
...
ext.useGoogleGcm = true
}
b {
...
ext.useGoogleGcm = false
}
}
然后在文件底部:
apply plugin: 'com.google.gms.google-services'
afterEvaluate {
android.productFlavors.each { flavor ->
tasks.matching {
it.name.contains('GoogleServices') && it.name.contains(flavor.name.capitalize())
}*.enabled = flavor.ext.useGoogleGcm
}
}
在您的 assembleRelease
任务的输出中,您应该会看到名称中带有“GoogleServices”的任务对于正确的任务有 运行,对于错误的任务则跳过。如果您的构建抱怨 toCapitalize
,您可以在 it.name
和 flavor.name
上使用 toLowerCase
。