如何应用插件,只有一个味道在梯度?

我有一个多口味,多构建类型的 android 项目,我想集成的 NewRelic 插件。但是我只能为一个顾客使用,因此只能为一种产品口味使用。
NewRelic 使用插装,如果我在那里应用插件,插件将生成其他风格的代码,这对我们来说是不允许的。

所以我的问题是: 我怎样才能使用级别文件中的 apply plugin: something命令只应用于我的一种口味?

13194 次浏览

我找到了一个解决方案,但目前还不是最好的。 所以我不再确定,我最初想做的是否可行。 渐变文件的评估以及正确风味和构建类型的选择处于渐变构建的不同阶段,因此我所做的是:

我使用命令行中的生成参数。当该参数为真时,我应用插件,当插件不存在时,我也应用它(用于 IDE 构建)。 我使用 Jenkins,这样就可以在构建作业中编写该参数。

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")
}
}

你必须这样运行渐变构建:

assembleYourApp -PcompileNewRelic=true
  1. 定义变量 -def fl
  2. 在 Flavours (和/或构建)中初始化变量

        productFlavors {
    
    
    freeFlavour {
    (...)
    fl = "free"
    }
    
    
    paidFlavour {
    (...)
    fl = "paid"
    }
    }
    
  3. Use if statement -

    if (fl == "free") { apply plugin: something }

使用以下代码:

if (!getGradle().getStartParameter().getTaskRequests()
.toString().contains("Develop")){
apply plugin: 'com.google.gms.google-services'
}

getGradle().getStartParameter().getTaskRequests().toString()返回类似于 [DefaultTaskExecutionRequest{args=[:app:generateDevelopDebugSources],projectPath='null'}]的内容,因此如注释中所述,Develop必须以大写字母开头。

尝试了不同的解决方案,但没有一个对我有效。这就是我想出来的,而且在我测试的时候似乎是有效的:

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'
}
}

我只是在 app level build.gradle 中的风格中使用了 apply plugin: 'com.google.gms.google-services',它工作得很好。

productFlavors {
..... your other flavors ....
yourFlv {
....
....
apply plugin: 'com.google.gms.google-services'
}
}

不需要额外的步骤。

以 GoogleServicesGradle 插件为例,可以使用以下工具。

apply plugin: 'com.google.gms.google-services'


afterEvaluate {
tasks.matching { it.name.contains("GoogleServices") && !it.name.contains(yourFlavorName) }*.enabled = false
}

其中 yourFlavorName是一个大写字符串,包含必须应用插件的口味名称; 所有其他口味不使用插件。

注意,这个插件仍然适用于其他风格; 这个解决方案只是禁用它们的 *GoogleServices*任务。这里假设 Google Services Gradle 插件仅通过添加一个包含子字符串 "GoogleServices"的任务来应用更改,将来这个任务可能无法工作。

要检查这是否有效,可以检查依赖关系,例如:

./gradlew app:dependencyInsight --configuration yourFlavorNameDebugCompileClasspath --dependency google | grep -i services

这将显示 yourFlavorName的一些依赖关系,但不会显示其他风味名称的依赖关系:

./gradlew app:dependencyInsight --configuration otherFlavorNameDebugCompileClasspath --dependency google | grep -i services

升级到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”的任务已经运行了那些为 true 的任务,而跳过了那些为 false 的任务。如果您的构建抱怨 toCapitalize,您可以在 it.nameflavor.name上使用 toLowerCase