Как применить плагин только к одному вкусу в градиенте?

У меня есть проект Android с множеством вкусов и типов сборки, и я хочу интегрировать плагин NewRelic. Но я должен применить его только для одного из клиентов, то есть только для одной разновидности продукта.
NewRelic использует инструментарий, и плагин генерировал бы код в других вариантах, если бы я применил плагин там, а это не разрешено для нас.

Итак, мой вопрос: как я могу использовать команду apply plugin: something в файле gradle, чтобы применить ее только к одному из моих вариантов?


person szidijani    schedule 13.07.2015    source источник


Ответы (6)


Используйте этот код:

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 должен начинаться с верхнего регистра.

person Pavel Santaev    schedule 11.04.2017
comment
Этот код работает. Но обратите внимание, что первая буква названия аромата должна быть в верхнем регистре. - person Phoenix Wang; 13.04.2017
comment
Не работало при нажатии на кнопку сборки из правого меню градиента ... При установке приложения вручную .. - person user3193413; 09.04.2018
comment
это почти работает для меня, но я заметил, когда набрал ./gradlew assembleDe, что значение в getTaskRequests также assembleDe - когда я ожидал, что оно уже будет расширено до assembleDebug - person Fabio; 09.02.2019
comment
Код не работает. Это напечатает пустой массив [] println ($ {getGradle (). GetStartParameter (). GetTaskRequests (). ToString ()}) - person Pavel; 27.12.2019
comment
Я подтвердил комментарий @Pavel. Кажется, работает из Android Studio, но не при запуске из командной строки. Это все, что я получаю: [DefaultTaskExecutionRequest {args = [build], projectPath = 'null'}] - person AlanKley; 04.09.2020
comment
У меня не работает, когда я очищаю, перестраиваю, получаю значение [defaulttaskexecutionrequest {args = [], projectpath = 'null'}] - person Velu; 30.03.2021
comment
@Fabio ты нашел решение проблемы? Например. запуск ./gradlew asF вместо ./gradlew assembleFlavor не дает решения, предложенного в этом ответе: строка запроса задачи содержит "asF", но не assembleFlavor. Это проблема при попытке сопоставления, например. "Flavor"! - person Erik; 18.06.2021
comment
Нет, я устал иметь дело с firebase и теперь распространяю Apks с помощью slack - person Fabio; 19.06.2021

Пробовал разные решения, но ни одно из них не помогло мне. Это то, что я придумал и, похоже, работает, насколько я тестировал:

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'
    }
}
person Tarps    schedule 21.11.2018
comment
Это было единственное решение, которое сработало для меня. Однако я немного изменил ваше if на if (getGradle().getStartParameter().getTaskNames().stream().filter { it.toLowerCase().contains(flavor.name) }.count() > 0 && flavor.ext.useGoogleGcm) - person Gabriel Gava; 26.11.2020
comment
Мне кажется, это не работает. Я как-то не получаю логи и плагин просто не применяется. Добавлены дополнительные логи перед оператором if, все равно без радости. - person Slion; 11.06.2021
comment
Кажется, что использование .all вместо .each исправляет это. - person Slion; 11.06.2021

  1. Определить переменную - def fl
  2. Инициализировать переменную в ваших ароматах (и / или сборках)

        productFlavors {
    
                freeFlavour {
                    (...)
                    fl = "free"
                }
    
                paidFlavour {
                    (...)
                    fl = "paid"
                }
            }
    
  3. Используйте оператор if -

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

person Sergey Bondarenko    schedule 20.09.2016
comment
Похоже, это не работает. В моем случае (скажем, я вызываю AssemblyFree) выполняются оба блока, поэтому значение fl - это имя последнего объявленного варианта. Есть другие идеи? - person daemontus; 14.01.2017
comment
Это будет разрешено во время настройки, и, поскольку это должно происходить повсюду, fl будет содержать последнее значение. - person l0v3; 28.11.2018

Я нашел решение, но пока оно не самое лучшее. Так что я больше не уверен, что то, что я хотел сделать изначально, возможно. Оценка файла 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
person szidijani    schedule 15.07.2015
comment
На сегодняшний день у меня это не работает. Очевидно, синтаксический анализатор build.gradle ищет операторы apply даже до оценки проекта, следовательно, аннулируя проверки if. - person Sebastiano; 23.05.2016

Я просто использовал apply plugin: 'com.google.gms.google-services' внутри аромата на уровне приложения build.gradle, и он отлично работает.

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

Никаких дополнительных шагов не требуется.

person mayank1513    schedule 29.08.2020
comment
Я бы посоветовал другим использовать это - person Ljdawson; 30.11.2020
comment
Вау, это действительно так просто! - person Nuwisam; 19.01.2021
comment
Я использовал его именно для этого варианта использования. У меня это сработало. - person lilienberg; 03.03.2021
comment
Спасибо за дополнения. Если это действительно помогло вам, вы можете нажать кнопку «проголосовать». Это поможет другим легко его найти. - person mayank1513; 03.03.2021
comment
Это работает для сборок через Android Studio, но не работает для сборок с Jenkins. - person anro; 26.03.2021
comment
Это чит-код синтаксиса, плагин по-прежнему задействован при сборке другого продукта, протестирован с плагином android gradle версии 4.2.0. - person yorkw; 14.07.2021

В случае плагина Google Services Gradle работает следующее.

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

person Erik    schedule 21.06.2021