Build Type — що це, конфігурація debug та release в Gradle

Автор: IT Sectr Опубліковано: 2026-05-30 Час читання: 9 хв

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 — конфігурація збірки з параметрами debuggable, minification, signing.
  • Debug — налагоджувальна збірка з debuggable=true, minification=false, debug.keystore.
  • Release — фінальна збірка з debuggable=false, minification=true, продакшн-підписом.
  • ProGuard та R8 виконують обфускацію, оптимізацію та стиснення коду в release-збірках.
  • BuildConfigField дозволяє задавати змінні, доступні в коді, окремо для кожного типу.

Що таке Build Type?

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 vs 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.

Стандартні Build Types: debug та release

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-збірки для автоматичного тестування на реальних пристроях перед публікацією.

groovy
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" }
        }
    }
}

Створення кастомних Build Types

Наслідування через initWith

На додаток до 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 довелося б вручну перераховувати всі параметри базового типу.

groovy
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 використовує його

Signing-конфігурація для різних типів збірки

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.

groovy
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, ProGuard та R8

Resource Shrinking

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%.

text
# 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.** { *; }

BuildConfigField та ресурси для Build Type

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).

kotlin
// 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
}

Поширені запитання

Чи можна мати debug-збірку з minification?

Так, створіть кастомний Build Type на кшталт debugMinified з initWith debug та увімкніть minification: debugMinified { initWith debug; minification true }. Це корисно для тестування правил ProGuard без збірки повної release-версії.

Як перевірити, що збірка release підписана правильно?

Виконайте apksigner з Android SDK: apksigner verify --print-certs app-release.apk. Якщо сертифікат збігається з тим, що завантажений у Google Play Console — підпис вірний. Також можна перевірити через jarsigner для старих форматів.

Що таке matchingFallbacks у Build Type?

matchingFallbacks вказує, який Build Type бібліотеки використовувати, якщо в неї немає потрібного типу. Наприклад, якщо у app є тип «staging», а в бібліотеки лише «release», AGP використовує release для бібліотеки. Вказується як список: matchingFallbacks = ["release", "debug"].

Як вимкнути minification для конкретної бібліотеки?

У правилах ProGuard використовуйте -keep для класів бібліотеки. Наприклад: -keep class com.some.library.** { *; }. Для повного вимкнення minification для всіх бібліотек вкажіть -dontobfuscate та -dontoptimize у proguard-rules.pro.

Чи впливає Build Type на версію API Android?

Build Type сам по собі не змінює minSdk або targetSdk. Але можна задати minSdk для конкретного Build Type: debug { minSdk 21 }. Це корисно для debug-збірок — можна підтримувати лише API 21+ для прискорення збірки, а release збирати на minSdk 26.

Підсумки

  • Build Type — інфраструктурна конфігурація збірки, що визначає налагодження, стиснення та підпис.
  • Debug — швидка збірка для розробки, release — оптимізована для публікації.
  • Кастомні Build Types (staging, benchmark) створюються через initWith для успадкування параметрів.
  • R8 виконує minification, обфускацію та resource shrinking, скорочуючи APK до 60%.
  • BuildConfigField та source sets дозволяють задавати змінні та ресурси для кожного типу.
  • Signing-ключі для release мають зберігатися поза репозиторієм — у CI/CD secrets або зашифрованому сховищі.
  • Рекомендація: завжди тестуйте release-збірку перед публікацією — debug не показує поведінку з minification.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також