Что такое BuildConfig и как его применять в проекте
BuildConfig — автоматически генерируемый класс Gradle в Android, который хранит константы сборки (версии, флаги debug, URL, ключи) и позволяет менять значения для debug/release/flavors без хардкода. Ниже — как задать поля, где их хранить и как безопасно использовать в коде.
Что содержит BuildConfig и зачем он нужен
BuildConfig генерируется при сборке и содержит:
- BuildConfig.DEBUG — автоматически true для debug‑сборок.
- Константы из build.gradle: buildConfigField("String", "API_URL", ""https://..."").
- Версии, флаги, фич‑флаги и значения, зависящие от buildType или flavor.
Зачем использовать:
- Типобезопасный доступ к конфигурации (компилятор проверяет типы).
- Разные значения для debug/release/staging без условий в коде.
- Простая интеграция с CI/CD (подстановка переменных окружения в Gradle).
Храните секреты вне репозитория (local.properties или gradle.properties) и подставляйте их в buildConfigField через properties — так вы снижаете риск утечки.
Как задать и сгенерировать BuildConfig
В Groovy DSL (build.gradle):
android {
defaultConfig {
applicationId "com.example.app"
buildConfigField "String", "API_URL", "\"https://api.example.com\""
}
buildTypes {
debug {
buildConfigField "boolean", "ENABLE_LOGGING", "true"
}
release {
buildConfigField "boolean", "ENABLE_LOGGING", "false"
minifyEnabled true
}
}
}
В Kotlin DSL (build.gradle.kts):
android {
defaultConfig {
buildConfigField("String", "APP_VERSION", "\"${versionName}\"")
buildConfigField("String", "API_KEY", "\"${properties["apiKey"] ?: ""}\"")
}
buildTypes {
debug {
buildConfigField("boolean", "ENABLE_LOGGING", "true")
}
release {
buildConfigField("boolean", "ENABLE_LOGGING", "false")
}
}
}
После ./gradlew clean assemble класс появится в build/generated/source/buildConfig/... Импорт: import com.yourapp.BuildConfig
Никогда не коммитьте local.properties с реальными ключами. Добавьте его в .gitignore.
Практическое использование и рекомендации
Примеры в коде:
if (BuildConfig.DEBUG) {
Log.d("Main", "Debug mode")
}
val client = Retrofit.Builder()
.baseUrl(BuildConfig.API_URL)
.build()
Советы:
- Для библиотек помните: у library‑модуля свой BuildConfig с пакетным именем модуля.
- Не храните длинные секректы в BuildConfig — значения включаются в APK и могут быть доступны при декомпиляции.
- Используйте local.properties/gradle.properties для хранения ключей CI: gradle.properties может храниться в CI-секретах и подтягиваться на сборке.
Сравнение способов хранения конфигурации
| Способ | Плюсы | Минусы |
|---|---|---|
| BuildConfig | Автогенерация, типобезопасно, удобно для флагов и URL | Значения попадают в APK (не для секретов) |
| local.properties / gradle.properties | Не в репозитории при правильной настройке | Нужно вручную синхронизировать между машинами |
| Product Flavors | Поддержка множества окружений | Увеличивает количество APK/вариантов |
| Remote Config (Firebase) | Меняется без пересборки | Зависимость от сети, задержка обновления |
Частые ошибки
- BuildConfig not found: проверьте applicationId, выполните Build > Clean Project > Rebuild.
- Хранение секретов в репозитории: не коммитить local.properties.
- Неправильно экранированные строки в Kotlin DSL: используйте ""value"" или rawString и проверяйте сборку.
- Ожидание runtime‑обновлений: BuildConfig — значение фиксируется в момент сборки.
FAQ
-
Нужно ли использовать BuildConfig для API‑ключей?
- Только если ключ не секретный. Для секретов используйте защищённые хранилища/серверные прокси или загружайте в runtime с защищённого бэкенда.
-
Как получать разные значения для staging и production?
- Создайте productFlavors или отдельные buildTypes и задайте buildConfigField для каждого варианта.
-
BuildConfig в модуле A доступен в модуле B?
- Нет: каждый модуль генерирует свой BuildConfig. Для общей конфигурации используйте общую библиотеку или ресурсно‑ориентированное решение.
Если нужно — могу привести готовые фрагменты для вашего build.gradle(.kts) с CI-подстановкой переменных.