如何在 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
  1. 定义变量 - def fl
  2. 在你的 Flavors 中初始化变量(and/or 构建)

        productFlavors {
    
                freeFlavour {
                    (...)
                    fl = "free"
                }
    
                paidFlavour {
                    (...)
                    fl = "paid"
                }
            }
    
  3. 使用 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.nameflavor.name 上使用 toLowerCase