Build Type w Android to konfiguracja Gradle, która określa, jak aplikacja jest budowana: z debugowaniem lub bez, z optymalizacją kodu lub bez, z jakim certyfikatem podpisu. Android Gradle Plugin udostępnia dwa standardowe Build Type — debug i release, a programista może dodawać własne, na przykład staging lub benchmark. Według Google Android Developers, 2025, prawidłowa konfiguracja Build Type zmniejsza rozmiar APK do 60% dzięki minification i resource shrinking. Każdy Build Type łączy się z Product Flavors w Build Variant.
Najważniejsze
Build Type — to element konfiguracji Gradle w projekcie Android, który opisuje parametry kompilacji i pakowania aplikacji. Każdy Build Type to nazwany zestaw opcji: debuggable (włączyć debugowanie), minificationEnabled (włączyć kompresję kodu), shrinkResources (włączyć kompresję zasobów), proguardFiles (pliki reguł ProGuard), signingConfig (certyfikat podpisu) i inne. Build Types są deklarowane w bloku android.buildTypes pliku build.gradle modułu app.
Głównym zadaniem Build Type jest rozdzielenie development workflow (szybkie budowanie, szczegółowe logi, debugowanie) i production release (zoptymalizowany kod, minimalny rozmiar, bezpieczeństwo). Debug powinien budować się w sekundach i dostarczać maksimum informacji programiście. Release powinien być maksymalnie szybki i kompaktowy dla użytkowników. Build Type to konfiguracja infrastrukturalna, niezwiązana z funkcjonalnością aplikacji.
Android Gradle Plugin automatycznie tworzy source set dla każdego Build Type — katalog src/<buildType>/ (na przykład src/debug/, src/release/). W tym source set można umieszczać zasoby, kod i manifest, które będą stosowane tylko dla danego typu budowania. Na przykład w src/debug/ można umieścić AndroidManifest.xml z uprawnieniem do instalacji z ADB, a w src/release/ — bez niego. Source set Build Type ma priorytet nad source set Product Flavor.
Kluczowa różnica: Build Type odpowiada na pytanie „jak budować?", a Product Flavor — na pytanie „co budować?". Build Type może być debug, release, staging. Product Flavor może być free, paid, enterprise. Build Type nie zmienia funkcjonalności aplikacji (nie dodaje ani nie usuwa ekranów), Product Flavor — zmienia. Build Type może wyłączyć debuger i włączyć obfuskację, Product Flavor — zmienić applicationId i zasoby. Oba działają w parze: każdy Build Type łączy się z każdym Product Flavor, tworząc Build Variant.
Debug — to Build Type tworzony przez AGP domyślnie. Zawiera debuggable=true, co umożliwia podłączenie debugera, przeglądanie logów Log.d i używanie profilera Android Studio. Minification jest wyłączone, więc budowanie jest szybkie. W wersji debug applicationId otrzymuje sufiks ".debug" (jeśli nie został nadpisany), co pozwala zainstalować wersję debug równolegle z wersją release na jednym urządzeniu. Debug jest podpisywany certyfikatem z debug.keystore, który jest tworzony automatycznie przez Android SDK.
Release — to Build Type do publikacji aplikacji. debuggable=false, minificationEnabled=true (domyślnie), shrinkResources=true. Programista musi określić signingConfig z certyfikatem produkcyjnym — w przeciwnym razie wersja nie będzie uznana za release. Release używa ProGuard lub R8 do obfuskacji, optymalizacji i kompresji kodu. Android Studio nie może podłączyć debugera do wersji release (jeśli debuggable=false). Wszystkie wywołania Log.d i Log.v są usuwane z kodu na etapie minification, jeśli skonfigurowano odpowiednie reguły ProGuard.
Ważne: wersje debug nie testują zachowania release. Minification może zmienić zachowanie kodu — reflection, serializacja, Gson/SQLite i inne biblioteki często wymagają reguł ProGuard. Dlatego przed publikacją należy zbudować wersję release i przetestować ją. Google Play Console i Firebase Test Lab umożliwiają przesyłanie wersji release do automatycznego testowania na rzeczywistych urządzeniach przed publikacją.
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" }
}
}
}
Oprócz debug i release można tworzyć własne Build Types — na przykład staging (środowisko przejściowe) lub benchmark (do testów wydajności). Niestandardowy Build Type jest deklarowany w bloku buildTypes tak samo jak debug i release. Nazwa może być dowolna, ale zaleca się używanie semantycznie zrozumiałych nazw w języku angielskim. Dla staging zwykle ustawia się debuggable=true (do diagnozowania problemów w środowisku staging) i minification=true (aby testować obfuskację przed produkcją).
Niestandardowy Build Type automatycznie otrzymuje odpowiadający source set (src/staging/) i generuje zadania typu assembleStaging. AGP nie nakłada ograniczeń na liczbę niestandardowych typów, ale każdy nowy typ mnoży liczbę Build Variants. Praktyczny limit to 4-5 Build Types: debug, staging, benchmark, release i ewentualnie debugMinified (debug z włączoną minification do testowania reguł ProGuard).
Dla niestandardowego Build Type można dziedziczyć debuggable z debug za pomocą initWith. Słowo kluczowe initWith kopiuje wszystkie parametry wskazanego Build Type, a następnie można je nadpisać. Jest to wygodne do tworzenia staging na podstawie debug: initWith debug + dodatkowo włączyć minification. Bez initWith trzeba by ręcznie wymieniać wszystkie parametry typu bazowego.
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 — dla bibliotek, które nie mają typu benchmark
// jeśli biblioteka ma tylko release — AGP go używa
SigningConfig określa, jakim certyfikatem podpisywany jest APK lub AAB. Android wymaga podpisu wszystkich instalowanych aplikacji — bez niego system nie pozwoli na instalację APK. Dla wersji debug AGP używa debug.keystore — preinstalowanego certyfikatu ze znanym hasłem, generowanego przez Android SDK Tools. Dla wersji release należy utworzyć własny certyfikat przez Android Studio (Build → Generate Signed Bundle/APK) lub za pomocą polecenia keytool.
Przechowywanie kluczy podpisu to krytyczny aspekt bezpieczeństwa. Zaleca się nie przechowywać kluczy release w repozytorium kodu źródłowego. Zamiast tego używa się: pliku keystore.properties (dodanego do .gitignore), zmiennych środowiskowych CI/CD lub zaszyfrowanego magazynu Android Studio. W CI/CD (GitHub Actions, GitLab CI) klucze podpisu są przechowywane w sekretach i przekazywane do build.gradle przez właściwości systemowe. Przykład: storePassword = System.getenv("KEYSTORE_PASSWORD").
Każdy Build Type może odwoływać się do własnego signingConfig. Dla release — certyfikat produkcyjny, dla debug — debug.keystore, dla staging — oddzielny certyfikat staging. Konfiguracja podpisu bezpośrednio wpływa na możliwość instalacji aplikacji: jeśli debug jest podpisany debug.keystore, a staging kluczem produkcyjnym, staging nie będzie można zainstalować na wersji debug z powodu niezgodności podpisów. ApplicationId również musi się różnić — w tym celu używa się 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 — to proces usuwania nieużywanego kodu i zmiany nazw klas, metod i pól na krótkie nazwy. AGP wykonuje minification za pomocą ProGuard (przestarzały) lub R8 (zalecany, wbudowany w AGP od wersji 3.4). R8 wykonuje cztery operacje: shrinking (usuwanie nieużywanych klas), optimisation (upraszczanie kodu), obfuscation (zmiana nazw) i preverify (dodawanie informacji o zgodności). Rezultat — APK o mniejszym rozmiarze, który trudniej dekompilować.
Reguły minification są definiowane w ProGuard rules files — plikach tekstowych ze składnią -keep, -dontwarn, -keepclassmembers. Bez reguł R8 usunie lub zmieni nazwy klas używanych przez reflection (Gson, Retrofit, Room, Kotlin serialization). Szablon projektu Android Studio tworzy proguard-rules.pro, do którego dodaje się reguły dla konkretnych bibliotek. Biblioteki mogą również zawierać wbudowane reguły — są one automatycznie dołączane z jar/aar.
Shrink resources (shrinkResources=true) usuwa nieużywane zasoby z APK. R8 najpierw określa, które zasoby nie są używane w kodzie (sprawdza R.java i odwołania w manifeście), a następnie usuwa je z końcowej wersji. Dla zasobów używanych przez getIdentifier() lub biblioteki zewnętrzne należy dodać tools:keep="@layout/my_layout" w zasobach. W połączeniu z minification, resource shrinking może zmniejszyć rozmiar APK o 40-60%.
# proguard-rules.pro — obowiązkowe reguły
# Gson: zachowaj klasy do serializacji
-keepclassmembers class com.example.** {
<fields>;
}
# Retrofit: zachowaj interfejsy API
-keep,allowobfuscation interface com.example.api.*
# Room: zachowaj DAO i Entity
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }
# Kotlin Coroutines: zapobiegaj usunięciu Continuation
-keepnames class kotlinx.coroutines.internal.*
# OkHttp: zachowaj service loader
-keep class okhttp3.** { *; }
BuildConfig — to automatycznie generowana klasa Java/Kotlin, która zawiera stałe zdefiniowane w defaultConfig, productFlavors i buildTypes. Przez buildConfigField można dodać niestandardowe pola: buildConfigField "String", "API_URL", '"https://api.example.com"'. BuildConfigField zadeklarowany w buildType jest dostępny we wszystkich wariantach tego typu. Wartości w buildType nadpisują wartości z productFlavor, które z kolei nadpisują defaultConfig.
Dla wersji debug wygodnie jest ustawić API_URL na localhost lub serwer staging, a dla release — na produkcyjny. BuildConfig.FLAVOR i BuildConfig.BUILD_TYPE również są generowane automatycznie i zawierają nazwę bieżącego flavor i build type. W kodzie można użyć: if (BuildConfig.DEBUG) { /* logi */ } — stała DEBUG jest równa true tylko dla build type debug. BuildConfig.DEBUG to standardowe pole, które AGP dodaje do każdego BuildConfig.
Zasoby dla Build Type są definiowane przez source set src/<buildType>/res/. Na przykład src/debug/res/values/strings.xml może zawierać tekst „Server: Dev", a src/release/res/ — „Server: Prod". Zasoby manifestu są również nadpisywane przez source set: src/debug/AndroidManifest.xml może zawierać <uses-permission android:name="android.permission.INTERNET" /> tylko dla wersji debug. Jest to czystsze niż sprawdzanie BuildConfig w kodzie i działa nawet dla atrybutów, których nie można ustawić programowo (na przykład 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
}
// Użycie: główna klasa ładuje Config przez reflection
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
"debug" -> DebugConfig
else -> ReleaseConfig
}
Często zadawane pytania
Tak, utwórz niestandardowy Build Type, np. debugMinified, z initWith debug i włącz minification: debugMinified { initWith debug; minification true }. Jest to przydatne do testowania reguł ProGuard bez budowania pełnej wersji release.
Uruchom apksigner z Android SDK: apksigner verify --print-certs app-release.apk. Jeśli certyfikat zgadza się z tym przesłanym do Google Play Console — podpis jest prawidłowy. Można również sprawdzić przez jarsigner dla starszych formatów.
matchingFallbacks określa, który Build Type biblioteki użyć, jeśli nie ma ona wymaganego typu. Na przykład, jeśli aplikacja ma typ „staging", a biblioteka tylko „release", AGP użyje release dla biblioteki. Jest podawany jako lista: matchingFallbacks = ["release", "debug"].
W regułach ProGuard użyj -keep dla klas biblioteki. Na przykład: -keep class com.some.library.** { *; }. Aby całkowicie wyłączyć minification dla wszystkich bibliotek, ustaw -dontobfuscate i -dontoptimize w proguard-rules.pro.
Build Type sam w sobie nie zmienia minSdk ani targetSdk. Można jednak ustawić minSdk dla konkretnego Build Type: debug { minSdk 21 }. Jest to przydatne dla wersji debug — można obsługiwać tylko API 21+ dla przyspieszenia budowania, a release budować na minSdk 26.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również