Ответ 1
Существует много возможных решений вашей проблемы. Самым естественным решением для Gradle должно быть использование Flavor Dimensions, как описано в http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Multi-flavor-variants
Это также похоже на то, о чем вы думали в решении 2.
Это будет работать примерно так:
flavorDimensions 'fruit', 'paid'
productFlavors {
apple {
dimension 'fruit'
}
orange {
dimension 'fruit'
}
free {
dimension 'paid'
}
premium {
dimension 'paid'
}
}
Это даст вам варианты сборки (и исходные папки), где она сочетает в себе все возможности из каждого размера вкуса, сохраняя тот же порядок, что и группы в вашем заявлении flavorDimensions
(т.е. appleFree
, а не freeApple
), таким образом:
* appleFree
* applePremium
* orangeFree
* orangePremium
в папке src/, вы можете иметь следующие возможности:
* src/main
* src/apple
* src/orange
* src/free
* src/premium
* src/appleFree
* src/applePremium
* src/orangeFree
* src/orangePremium
Решение 3
Вы можете использовать buildConfigField
для указания констант, которые входят в класс BuildConfig
по принципу "за вкусом":
productFlavors {
appleFree {
buildConfigField 'String', 'MY_URL', 'value1'
}
applePremium {
buildConfigField 'String', 'MY_URL', 'value2'
}
orangeFree {
buildConfigField 'String', 'MY_URL', 'value3'
}
orangePremium {
buildConfigField 'String', 'MY_URL', 'value4'
}
Решение 1
Я пытался что-то решить в соответствии с решением 1, но это не сработает для вашего конкретного случая использования. Если у вас есть условие if
в Java, которое проверяет логическое значение, объявленное static final
, тогда компилятор может определить статически, доступен ли код или нет, и он разделит его, если он не будет. Таким образом:
static final boolean DEBUG = false;
...
if (DEBUG) {
// do something
}
Код в // do something
не будет компилироваться вообще. Это преднамеренное и документированное поведение со стороны компилятора Java и позволяет писать дорогой код отладки, который не будет скомпилирован в ваш двоичный файл release. BuildConfig.DEBUG
для этой точной причины объявляется static final
.
Там a BuildConfig.FLAVOR
, но он определен как String
, и вы не получите того же преимущества:
static final String FLAVOR = "orange";
...
if (FLAVOR.equals("apple")) {
// do something
}
Компилятор недостаточно умен, чтобы делать статический анализ, см., что // do something
недоступен, а не компилирует его. Обратите внимание, что он будет работать нормально во время выполнения, но этот мертвый код будет включен в ваш двоичный файл.
Если вам это подходит, вы можете украсть подход buildConfigField
сверху и определить дополнительную логическую переменную в некоторых вариантах, которые могут позволить условно скомпилировать код. Это сложнее, чем определение строки непосредственно, как в Решение 3, но если вы обнаружите, что хотите различать поведение, не сталкиваясь с проблемой создания подклассов, специфичных для вашего вкуса, вы можете пойти по этому пути.