Android Studio: сочетание вкуса продукта с более чем двумя измерениями вкуса (группы вкусов)
Я разрабатываю приложение для Android с помощью Android Studio (v 2.1, Gradle Plugin v 2.1.0). У моего приложения есть различные версии, которые имеют много общего кода, поэтому я решил использовать измерения вкусов и вкусов продуктов для настройки кода и ресурсов, когда и где он запрашивается. Это оштрафовано до тех пор, пока у меня было только два вкуса. В качестве примера мой app.gradle
было
…
flavorDimensions "fruit", "color"
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
}
…
и мой src
папка была
src/
appleRed/
appleYellow/
pearRed/
pearYellow/
каждый со своей версией моего кода. Опять же в качестве примера
src/
appleRed/java/com/example/ExampleFragment.java
appleYellow/java/com/example/ExampleFragment.java
pearRed/java/com/example/ExampleFragment.java
pearYellow/java/com/example/ExampleFragment.java
конечно, нет ни одного случая ExampleFragment
в src/main
,
В какой-то момент в процессе разработки мне пришлось включить бесплатную и платную версию приложения. Я думал, что это может быть легко достигнуто путем добавления нового измерения вкуса с именем version
и два продукта названы free
а также paid
:
…
flavorDimensions "fruit", "color”, “version”
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
free {
dimension "version"
}
paid {
dimension “version”
}
}
…
но вдруг пользовательский код, сгенерированный комбинацией fruit
а также color
Android Studio больше не был обнаружен. Так нет appleRed
, appleYellow
, pearRed
ни pearYellow
можно использовать для создания пользовательского кода, и единственный способ восстановить конфигурацию - использовать все комбинации всех трех измерений:
src/
appleRedFree/java/com/example/ExampleFragment.java
appleRedPaid/java/com/example/ExampleFragment.java
appleYellowFree/java/com/example/ExampleFragment.java
appleYellowPaid/java/com/example/ExampleFragment.java
pearRedFree/java/com/example/ExampleFragment.java
pearRedPaid/java/com/example/ExampleFragment.java
pearYellowFree/java/com/example/ExampleFragment.java
pearYellowPaid/java/com/example/ExampleFragment.java
Это не хорошо, потому что ExampleFragment
дублируется через один и тот же fruitColor*
комбинация (appleRedFree
, appleRedPaid
имеют те же ExampleFragment
). Та же проблема происходит с ресурсами (те, в res
папка).
Мои вопросы:
1) Является ли это ожидаемым поведением gradle в Android Studio (т. Е. Неспособность объединить подмножество вкусов продукта, следуя их приоритету на основе их измерения, когда имеется более двух измерений аромата)?
2) Учитывая тот факт, что это ожидаемое поведение, есть ли другой способ, с помощью которого я могу выполнить свою настройку без дублированного кода или без одного файла с оператором if внутри (например, if (BuildConfig.FLAVOR_version == "free") ...
)
Пожалуйста, обратите внимание, что я имею в виду наличие пользовательского кода, который может быть сложным, поэтому я не прошу базовой настройки, такой как переменная конфигурации сборки, фильтрация вариантов или что-то в этом роде.
1 ответ
Вы хотите использовать один и тот же дополнительный исходный каталог для некоторых разновидностей;
appleRedFree + appleRedPaid -> src / appleRed
pearRedFree + pearRedPaid -> src / pearRed
appleYellowFree + appleYellowPaid -> src / appleYellow
pearYellowFree + pearYellowPaid -> src / pearYellow
Вы можете установить sourceSet для своих вкусов:
android {
// Other stuff here
flavorDimensions "fruit", "color”, “version”
productFlavors {
apple {
dimension "fruit"
}
pear {
dimension "fruit"
}
red {
dimension "color"
}
yellow {
dimension "color"
}
free {
dimension "version"
}
paid {
dimension “version”
}
}
sourceSets {
appleRedFree {
java.srcDirs = ['src/main/java', 'src/appleRed/java']
}
appleRedPaid {
java.srcDirs = ['src/main/java', 'src/appleRed/java']
}
appleYellowFree {
java.srcDirs = ['src/main/java', 'src/appleYellow/java']
}
appleYellowPaid {
java.srcDirs = ['src/main/java', 'src/appleYellow/java']
}
pearRedFree {
java.srcDirs = ['src/main/java', 'src/pearRed/java']
}
pearRedPaid {
java.srcDirs = ['src/main/java', 'src/pearRed/java']
}
pearYellowFree {
java.srcDirs = ['src/main/java', 'src/pearYellow/java']
}
pearYellowPaid {
java.srcDirs = ['src/main/java', 'src/pearYellow/java']
}
}
// Other stuff here
}
У меня есть небольшое улучшение, потому что я действительно не люблю копировать / вставлять наборы src:)
Итак, вы можете сделать что-то вроде этого:
android {
…
applicationVariants.all { variant ->
def flavors = variant.productFlavors
def fruit = flavors[0].name
def color = flavors[1].name
def version = flavors[2].name
def fruitColorSrcSet = fruit + color.capitalize()
def srcSet = fruitColorSrcSet + version.capitalize()
android.sourceSets."$srcSet".java.srcDirs += "src/$fruitColorSrcSet/java"
}
}
Я не тестировал его, но он основан на моей текущей реализации с дополнительным variant.buildType.name
Применение
Приложение - для настройки использования каталога ресурсов
android.sourceSets."$srcSet".res.srcDirs = "src/$fruitColorSrcSet/res"