Build Type в Android-розробці — це конфігурація Gradle, яка визначає, як застосунок збирається: з налагодженням чи без, з оптимізацією коду чи без, з яким сертифікатом підпису. Android Gradle Plugin надає два стандартних Build Type — debug та release, а розробник може додавати власні, наприклад staging або benchmark. За даними Google Android Developers, 2025, правильне налаштування Build Type скорочує розмір APK до 60% завдяки minification та resource shrinking. Кожен Build Type комбінується з Product Flavors у Build Variant.
Головне
Build Type — це елемент Gradle-конфігурації Android-проєкту, який описує параметри компіляції та пакування застосунку. Кожен Build Type являє собою іменований набір опцій: debuggable (увімкнути налагодження), minificationEnabled (увімкнути стиснення коду), shrinkResources (увімкнути стиснення ресурсів), proguardFiles (файли правил ProGuard), signingConfig (сертифікат підпису) та інші. Build Types оголошуються в блоці android.buildTypes файлу build.gradle модуля app.
Основне завдання Build Type — розділити development workflow (швидка збірка, докладні логи, налагодження) та production release (оптимізований код, мінімальний розмір, безпека). Debug-збірка має збиратися за секунди та надавати максимум інформації розробнику. Release-збірка має бути максимально швидкою та компактною для користувачів. Build Type — це інфраструктурне налаштування, не пов'язане з функціональністю застосунку.
Android Gradle Plugin автоматично створює source set для кожного Build Type — директорію src/<buildType>/ (наприклад, src/debug/, src/release/). Ресурси, код та маніфест, розміщені в цьому source set, застосовуються лише для даного типу збірки. Наприклад, у src/debug/ можна розмістити AndroidManifest.xml з дозволом на встановлення з ADB, а в src/release/ — без нього. Source set Build Type має пріоритет над source set Product Flavor.
Ключова відмінність: Build Type відповідає на питання «як збирати?», а Product Flavor — на питання «що збирати?». Build Type може бути debug, release, staging. Product Flavor може бути free, paid, enterprise. Build Type не змінює функціональність застосунку (не додає та не прибирає екрани), Product Flavor — змінює. Build Type може вимкнути налагоджувач та увімкнути обфускацію, Product Flavor — змінити applicationId та ресурси. Обидва працюють у парі: кожен Build Type комбінується з кожним Product Flavor, утворюючи Build Variant.
Debug — це Build Type, створюваний AGP за замовчуванням. Він включає debuggable=true, що дозволяє підключити налагоджувач, переглядати логи Log.d та використовувати профілювальник Android Studio. Minification вимкнено, тому збірка відбувається швидко. У debug-збірці applicationId отримує суфікс «.debug» (якщо не перевизначено), що дозволяє встановити debug-версію паралельно з release-версією на одному пристрої. Debug-збірка підписується сертифікатом з debug.keystore, який створюється Android SDK автоматично.
Release — це Build Type для публікації застосунку. debuggable=false, minificationEnabled=true (за замовчуванням), shrinkResources=true. Розробник зобов'язаний вказати signingConfig з продакшн-сертифікатом — інакше збірка не вважатиметься релізною. Release-збірка використовує ProGuard або R8 для обфускації, оптимізації та стиснення коду. Android Studio не може підключити налагоджувач до release-збірки (якщо debuggable=false). Усі виклики Log.d та Log.v видаляються з коду на етапі minification, якщо налаштовані відповідні правила ProGuard.
Важливо: debug-збірки не тестують поведінку release. Minification може змінити поведінку коду — reflection, серіалізація, Gson/SQLite та інші бібліотеки часто вимагають правил ProGuard. Тому перед публікацією обов'язково збирайте release-збірку та тестуйте її. Google Play Console та Firebase Test Lab дозволяють завантажувати release-збірки для автоматичного тестування на реальних пристроях перед публікацією.
android {
buildTypes {
debug {
debuggable true
minification false
signingConfig signingConfigs.debug
versionNameSuffix "-debug"
}
release {
debuggable false
minification true
shrinkResources true
proguardFiles "proguard-rules.pro"
signingConfig signingConfigs.release
ndk { abiFilters "arm64-v8a", "x86_64" }
}
}
}
На додаток до debug та release можна створювати власні Build Types — наприклад staging (проміжне середовище) або benchmark (для тестів продуктивності). Кастомний Build Type оголошується в блоці buildTypes так само, як debug та release. Ім'я може бути будь-яким, але рекомендується використовувати семантично зрозумілі назви англійською мовою. Для staging зазвичай встановлюють debuggable=true (для діагностики проблем у staging-середовищі) та minification=true (щоб тестувати обфускацію до продакшну).
Кастомний Build Type автоматично отримує відповідний source set (src/staging/) та генерує завдання виду assembleStaging. AGP не накладає обмежень на кількість кастомних типів, але кожен новий тип множить кількість Build Variants. Практичний ліміт — 4-5 Build Types: debug, staging, benchmark, release, і, можливо, debugMinified (debug з увімкненою minification для тестування правил ProGuard).
Для кастомного Build Type можна успадкувати debuggable від debug за допомогою initWith. Ключове слово initWith копіює всі параметри вказаного Build Type, після чого їх можна перевизначити. Це зручно для створення staging на основі debug: initWith debug + додатково увімкнути minification. Без initWith довелося б вручну перераховувати всі параметри базового типу.
android {
buildTypes {
staging {
initWith debug
minification true
shrinkResources true
proguardFiles "staging-proguard-rules.pro"
versionNameSuffix "-staging"
}
benchmark {
initWith release
signingConfig signingConfigs.debug
matchingFallbacks = ["release"]
}
}
}
// matchingFallbacks — для бібліотек, у яких немає benchmark типу
// якщо бібліотека має лише release — AGP використовує його
SigningConfig визначає, яким сертифікатом підписується APK або AAB. Android вимагає підпису всіх встановлюваних застосунків — без неї система не дозволить встановити APK. Для debug-збірок AGP використовує debug.keystore — попередньо встановлений сертифікат з відомим паролем, який генерується Android SDK Tools. Для release-збірок необхідно створити власний сертифікат через Android Studio (Build → Generate Signed Bundle/APK) або командою keytool командного рядка.
Зберігання signing-ключів — критичний аспект безпеки. Рекомендується не зберігати release-ключі в репозиторії вихідного коду. Натомість використовуються: файл keystore.properties (доданий до .gitignore), змінні середовища CI/CD або зашифроване сховище Android Studio. У CI/CD (GitHub Actions, GitLab CI) signing-ключі зберігаються в secrets та передаються в build.gradle через системні властивості. Приклад: storePassword = System.getenv("KEYSTORE_PASSWORD").
Кожен Build Type може посилатися на свій signingConfig. Для release — продакшн-сертифікат, для debug — debug.keystore, для staging — окремий staging-сертифікат. Signing-конфігурація безпосередньо впливає на можливість встановлення застосунку: якщо підписати debug debug.keystore, а staging — продакшн-ключем, staging не можна буде встановити поверх debug-версії через несумісність підписів. ApplicationId теж має відрізнятися — для цього використовується applicationIdSuffix.
android {
signingConfigs {
debug {
storeFile file("debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
release {
storeFile file("release-key.jks")
storePassword System.getenv("KEYSTORE_PASS")
keyAlias "my-key"
keyPassword System.getenv("KEY_PASS")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Minification — це процес видалення невикористовуваного коду та перейменування класів, методів і полів у короткі імена. AGP виконує minification за допомогою ProGuard (застарілий) або R8 (рекомендований, вбудований в AGP починаючи з версії 3.4). R8 виконує чотири операції: shrinking (видалення невикористовуваних класів), optimisation (спрощення коду), obfuscation (перейменування) та preverify (додавання інформації для сумісності). Результат — APK меншого розміру, який складніше декомпілювати.
Правила minification задаються в файлах правил ProGuard — текстових файлах із синтаксисом -keep, -dontwarn, -keepclassmembers. Без правил R8 видалить або перейменує класи, що використовуються через reflection (Gson, Retrofit, Room, Kotlin-серіалізація). Шаблон проєкту Android Studio створює proguard-rules.pro, куди додаються правила для конкретних бібліотек. Бібліотеки також можуть містити вбудовані правила — вони автоматично підключаються з jar/aar.
Shrink resources (shrinkResources=true) видаляє невикористовувані ресурси з APK. R8 спочатку визначає, які ресурси не використовуються в коді (перевіряє R.java та посилання в маніфесті), після чого видаляє їх з фінальної збірки. Для ресурсів, що використовуються через getIdentifier() або сторонніми бібліотеками, необхідно додати tools:keep="@layout/my_layout" у ресурсах. У поєднанні з minification, resource shrinking може зменшити розмір APK на 40-60%.
# proguard-rules.pro — обов'язкові правила
# Gson: зберегти класи для серіалізації
-keepclassmembers class com.example.** {
<fields>;
}
# Retrofit: зберегти інтерфейси API
-keep,allowobfuscation interface com.example.api.*
# Room: зберегти DAO та Entity
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }
# Kotlin Coroutines: запобігти видаленню Continuation
-keepnames class kotlinx.coroutines.internal.*
# OkHttp: збереження service loader
-keep class okhttp3.** { *; }
BuildConfig — це автоматично генерований клас Java/Kotlin, який містить константи, визначені в defaultConfig, productFlavors та buildTypes. Через buildConfigField можна додати кастомні поля: buildConfigField "String", "API_URL", '"https://api.example.com"'. BuildConfigField, оголошений у buildType, доступний у всіх варіантах цього типу. Значення в buildType перевизначають значення з productFlavor, які, своєю чергою, перевизначають defaultConfig.
Для debug-збірок зручно задавати API_URL на localhost або staging-сервер, для release — на production. BuildConfig.FLAVOR та BuildConfig.BUILD_TYPE також генеруються автоматично та містять ім'я поточного flavor та build type. У коді можна використовувати: if (BuildConfig.DEBUG) { /* логи */ } — константа DEBUG дорівнює true лише для debug build type. BuildConfig.DEBUG — це стандартне поле, яке AGP додає в кожен BuildConfig.
Ресурси для Build Type задаються через source set src/<buildType>/res/. Наприклад, src/debug/res/values/strings.xml може містити рядок «Server: Dev», а src/release/res/ — «Server: Prod». Ресурси маніфесту також перевизначаються через source set: src/debug/AndroidManifest.xml може включати <uses-permission android:name="android.permission.INTERNET" /> лише для debug-збірок. Це чистіше, ніж перевірка BuildConfig у коді, і працює навіть для атрибутів, які не можна задати програмно (наприклад, networkSecurityConfig).
// src/debug/kotlin/.../DebugConfig.kt
object DebugConfig {
val apiUrl = "http://localhost:8080/api"
val enableLogging = true
val enableCrashReporting = false
}
// src/release/kotlin/.../ReleaseConfig.kt
object ReleaseConfig {
val apiUrl = "https://api.production.com/v2"
val enableLogging = false
val enableCrashReporting = true
}
// Використання: головний клас завантажує Config через reflection
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
"debug" -> DebugConfig
else -> ReleaseConfig
}
Поширені запитання
Так, створіть кастомний Build Type на кшталт debugMinified з initWith debug та увімкніть minification: debugMinified { initWith debug; minification true }. Це корисно для тестування правил ProGuard без збірки повної release-версії.
Виконайте apksigner з Android SDK: apksigner verify --print-certs app-release.apk. Якщо сертифікат збігається з тим, що завантажений у Google Play Console — підпис вірний. Також можна перевірити через jarsigner для старих форматів.
matchingFallbacks вказує, який Build Type бібліотеки використовувати, якщо в неї немає потрібного типу. Наприклад, якщо у app є тип «staging», а в бібліотеки лише «release», AGP використовує release для бібліотеки. Вказується як список: matchingFallbacks = ["release", "debug"].
У правилах ProGuard використовуйте -keep для класів бібліотеки. Наприклад: -keep class com.some.library.** { *; }. Для повного вимкнення minification для всіх бібліотек вкажіть -dontobfuscate та -dontoptimize у proguard-rules.pro.
Build Type сам по собі не змінює minSdk або targetSdk. Але можна задати minSdk для конкретного Build Type: debug { minSdk 21 }. Це корисно для debug-збірок — можна підтримувати лише API 21+ для прискорення збірки, а release збирати на minSdk 26.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також