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.add
API, который принимает 2 параметра:
- Тип зависимости, например
implementation
,api
,flavor1Implementation
. Это может быть строка, что позволяет нам использовать манипуляции со строками для динамического создания этого значения. - Сама зависимость, например
"com.example.test:test:1.0.0"
,project(':local')
.
Используя этот API, вы можете динамически добавлять зависимости с большой гибкостью!