Android gradle: разделение зависимостей между разновидностями продукта

У меня в приложении 3 вкуса продукта (flavor1, flavore2, flavour3). flavour1 и flav2 разделяют некоторые зависимости, связанные с рекламой.

Есть ли способ связать связанные с рекламой зависимости в измерении или конфигурации gradle и добавить их в flavor и flav2 без дублирования строк compileFlavor1 и compileFlavor2 в моем build.gradle?

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

android {
    productFlavors {
        flavor1 {}
        flavor2 {}
        flavor3 {}
    }

    sourceSets {
       main {}
       flavor1.java.srcDir 'common/ads/java'     <--- shared sourceSet
       flavor2.java.srcDir 'common/ads/java'
       flavor3.java.srcDir 'common/no_ads/java'
    }
}

dependencies {
    compile 'dependency1'
    compile 'dependency2'

    compileFlavor1 'dependency3'   <----- Same list
    compileFlavor1 'dependency4'
    compileFlavor1 'dependency5'

    compileFlavor2 'dependency3'   <------ Same list
    compileFlavor2 'dependency4'
    compileFlavor2 'dependency5
}

3 ответа

Решение для разделения зависимостей между разновидностями (обновлено для implementation который теперь заменил compile):

поскольку implementation, flavor1Implementation, flavor2Implementationи т. д. все они на самом деле являются конфигурациями, которые вы можете применить к наследованию между этими шагами в процессе сборки.

Следовательно, в этом случае вы можете указать свои общие зависимости и зависимости для flavor1 только:

dependencies {
    implementation 'dependency1'
    implementation 'dependency2'

    flavor1Implementation 'dependency3'
    flavor1Implementation 'dependency4'
    flavor1Implementation 'dependency5'
}

... а потом просто разрешить flavor2Implementation наследовать от flavor1Implementation:

configurations.flavor2Implementation.extendsFrom(flavor1Implementation)

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

configurations {
    flavor3Implementation.extendsFrom(
            flavor1Implementation,
            flavor2Implementation
    )
}

(Наконец, просто обратите внимание, что совместное использование кода между разновидностями должно быть продолжено с sourceSets согласно первоначальному вопросу.)

Вот что мы сделали, чтобы разделить каталоги между разными вкусами:

sourceSets {
    main {
      java.srcDirs = ['src/main/java']
      res.srcDirs = ['src/main/res']
      assets.srcDirs = ['src/main/assets']
    }
    production {
      java.srcDirs = ['src/main/java', 'src/shared/java']
      res.srcDirs = ['src/main/res', 'src/shared/res']
      assets.srcDirs = ['src/main/assets', 'src/shared/assets']
    }
    logger {
      java.srcDirs = ['src/main/java', 'src/shared/java', 'src/mock/java']
      res.srcDirs = ['src/main/res', 'src/shared/res']
      assets.srcDirs = ['src/main/assets', 'src/shared/assets']
    }
    nowav {
      java.srcDirs = ['src/main/java', 'src/nowav/java', 'src/mock/java']
      res.srcDirs = ['src/main/res', 'src/nowav/res']
      assets.srcDirs = ['src/main/assets', 'src/nowav/assets']
    }
}

Я не смог найти аккуратного способа сделать это (наследование ароматов мне не подходит), поэтому я написал для этого небольшую утилиту.

Полезность

Просто добавьте эти функции перед вашимdependenciesблокировать:

      /** Adds [dependency] as a dependency for the flavor [flavor] */
dependencies.ext.flavorImplementation = { flavor, dependency ->
    def cmd = "${flavor}Implementation"
    dependencies.add(cmd, dependency)
}

/** Adds [dependency] as a dependency for every flavor in [flavors] */
dependencies.ext.flavorsImplementation = { flavors, dependency ->
    flavors.each { dependencies.flavorImplementation(it, dependency) }
}

Применение

Вы используете утилиту следующим образом:

      dependencies {
    ...
    def myFlavors = ["flavor1", "flavor2", "flavor3"]
    flavorsImplementation(myFlavors, "com.example.test:test:1.0.0")
    flavorsImplementation(myFlavors, project(':local'))
    ...
}

Как это работает

Ключом к этой утилите является Gradledependencies.addAPI, который принимает 2 параметра:

  1. Тип зависимости, напримерimplementation,api,flavor1Implementation. Это может быть строка, что позволяет нам использовать манипуляции со строками для динамического создания этого значения.
  2. Сама зависимость, например"com.example.test:test:1.0.0",project(':local').

Используя этот API, вы можете динамически добавлять зависимости с большой гибкостью!

Другие вопросы по тегам