Build Type în dezvoltarea Android este o configurație Gradle care determină cum este construită aplicația: cu depanare sau fără, cu optimizare de cod sau fără, cu ce certificat de semnare. Android Gradle Plugin oferă două Build Type standard — debug și release, iar dezvoltatorul poate adăuga propriile tipuri, de exemplu staging sau benchmark. Conform Google Android Developers, 2025, configurarea corectă a Build Type reduce dimensiunea APK cu până la 60% datorită minification și resource shrinking. Fiecare Build Type se combină cu Product Flavors în Build Variant.
Principalele puncte
Build Type este un element al configurației Gradle a proiectului Android care descrie parametrii de compilare și ambalare a aplicației. Fiecare Build Type reprezintă un set numit de opțiuni: debuggable (activarea depanării), minificationEnabled (activarea comprimării codului), shrinkResources (activarea comprimării resurselor), proguardFiles (fișierele de reguli ProGuard), signingConfig (certificatul de semnare) și altele. Build Types sunt declarate în blocul android.buildTypes al fișierului build.gradle al modulului app.
Sarcina principală a Build Type este separarea development workflow (build rapid, loguri detaliate, depanare) și production release (cod optimizat, dimensiune minimă, securitate). Build-ul debug trebuie să se construiască în câteva secunde și să ofere maximum de informații dezvoltatorului. Build-ul release trebuie să fie cât mai rapid și compact pentru utilizatori. Build Type este o configurație infrastructurală, nelegată de funcționalitatea aplicației.
Android Gradle Plugin creează automat source set pentru fiecare Build Type — directorul src/<buildType>/ (de exemplu, src/debug/, src/release/). În acest source set pot fi plasate resurse, cod și manifest care se aplică doar pentru acel tip de build. De exemplu, în src/debug/ poate fi plasat AndroidManifest.xml cu permisiunea de instalare din ADB, iar în src/release/ — fără aceasta. Source set Build Type are prioritate față de source set Product Flavor.
Diferența cheie: Build Type răspunde la întrebarea “cum să construim?”, iar Product Flavor — la întrebarea “ce să construim?”. Build Type poate fi debug, release, staging. Product Flavor poate fi free, paid, enterprise. Build Type nu schimbă funcționalitatea aplicației (nu adaugă sau elimină ecrane), Product Flavor — da. Build Type poate dezactiva debuggerul și activa ofuscarea, Product Flavor poate modifica applicationId și resursele. Ambele lucrează în pereche: fiecare Build Type se combină cu fiecare Product Flavor, formând Build Variant.
Debug este Build Type creat implicit de AGP. Acesta include debuggable=true, ceea ce permite conectarea debuggerului, vizualizarea logurilor Log.d și utilizarea profilerului din Android Studio. Minification este dezactivat, deci build-ul este rapid. În build-ul debug, applicationId primește sufixul “.debug” (dacă nu a fost suprascris), ceea ce permite instalarea versiunii debug în paralel cu versiunea release pe același dispozitiv. Debug este semnat cu certificatul din debug.keystore, care este creat automat de Android SDK.
Release este Build Type pentru publicarea aplicației. debuggable=false, minificationEnabled=true (implicit), shrinkResources=true. Dezvoltatorul trebuie să specify signingConfig cu certificatul de producție — altfel build-ul nu este considerat release. Release folosește ProGuard sau R8 pentru ofuscarea, optimizarea și comprimarea codului. Android Studio nu se poate conecta cu debuggerul la un build release (dacă debuggable=false). Toate apelurile Log.d și Log.v sunt eliminate din cod în faza de minification, dacă sunt configurate regulile ProGuard corespunzătoare.
Important: build-urile debug nu testează comportamentul release. Minification poate modifica comportamentul codului — reflection, serializarea, Gson/SQLite și alte biblioteci necesită adesea reguli ProGuard. De aceea, înainte de publicare, trebuie să construiți și să testați build-ul release. Google Play Console și Firebase Test Lab permit încărcarea build-urilor release pentru testare automată pe dispozitive reale înainte de publicare.
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" }
}
}
}
Pe lângă debug și release, puteți crea propriile Build Types — de exemplu staging (mediu intermediar) sau benchmark (pentru teste de performanță). Un Build Type personalizat este declarat în blocul buildTypes la fel ca debug și release. Numele poate fi oricare, dar se recomandă utilizarea unor nume semnificative în limba engleză. Pentru staging, de obicei se setează debuggable=true (pentru diagnosticarea problemelor în mediul staging) și minification=true (pentru a testa ofuscarea înainte de producție).
Build Type personalizat primește automat source set-ul corespunzător (src/staging/) și generează sarcini de tip assembleStaging. AGP nu impune limite privind numărul de tipuri personalizate, dar fiecare tip nou multiplică numărul de Build Variants. Limita practică este de 4-5 Build Types: debug, staging, benchmark, release și, eventual, debugMinified (debug cu minification activată pentru testarea regulilor ProGuard).
Pentru un Build Type personalizat, debuggable poate fi moștenit de la debug folosind initWith. Cuvântul cheie initWith copiază toți parametrii Build Type-ului specificat, după care aceștia pot fi suprascriși. Acest lucru este util pentru crearea staging pe baza debug: initWith debug + activarea suplimentară a minification. Fără initWith, ar trebui să enumerați manual toți parametrii tipului de bază.
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 — pentru bibliotecile care nu au tipul benchmark
// dacă biblioteca are doar release — AGP îl folosește
SigningConfig determină cu ce certificat este semnat APK sau AAB. Android cere semnarea tuturor aplicațiilor instalabile — fără ea, sistemul nu va permite instalarea APK-ului. Pentru build-urile debug, AGP folosește debug.keystore — un certificat preinstalat cu o parolă cunoscută, generat de Android SDK Tools. Pentru build-urile release, trebuie să creați propriul certificat prin Android Studio (Build → Generate Signed Bundle/APK) sau prin comanda keytool.
Stocarea cheilor de semnare este un aspect critic de securitate. Se recomandă să nu stocați cheile release în depozitul de cod sursă. În schimb, se folosesc: fișierul keystore.properties (adăugat în .gitignore), variabilele de mediu CI/CD sau depozitul criptat al Android Studio. În CI/CD (GitHub Actions, GitLab CI), cheile de semnare sunt stocate în secrets și transmise în build.gradle prin proprietăți de sistem. Exemplu: storePassword = System.getenv("KEYSTORE_PASSWORD").
Fiecare Build Type poate face referire la propriul signingConfig. Pentru release — certificatul de producție, pentru debug — debug.keystore, pentru staging — un certificat staging separat. Configurarea semnării influențează direct posibilitatea de instalare a aplicației: dacă debug este semnat cu debug.keystore, iar staging cu cheia de producție, staging nu poate fi instalat peste versiunea debug din cauza nepotrivirii semnăturilor. ApplicationId trebuie de asemenea să difere — pentru aceasta se folosește 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 este procesul de eliminare a codului neutilizat și de redenumire a claselor, metodelor și câmpurilor cu nume scurte. AGP execută minification cu ajutorul ProGuard (învechit) sau R8 (recomandat, încorporat în AGP începând cu versiunea 3.4). R8 efectuează patru operații: shrinking (eliminarea claselor neutilizate), optimisation (simplificarea codului), obfuscation (redenumirea) și preverify (adăugarea informațiilor de compatibilitate). Rezultatul — un APK de dimensiuni mai mici, care este mai greu de decompliat.
Regulile de minification sunt definite în ProGuard rules files — fișiere text cu sintaxa -keep, -dontwarn, -keepclassmembers. Fără reguli, R8 va elimina sau redenumi clasele utilizate prin reflection (Gson, Retrofit, Room, Kotlin serialization). Șablonul de proiect Android Studio creează proguard-rules.pro, unde se adaugă reguli pentru bibliotecile specifice. Bibliotecile pot conține, de asemenea, reguli încorporate — acestea sunt conectate automat din jar/aar.
Shrink resources (shrinkResources=true) elimină resursele neutilizate din APK. R8 determină mai întâi care resurse nu sunt utilizate în cod (verifică R.java și referințele din manifest), apoi le elimină din build-ul final. Pentru resursele utilizate prin getIdentifier() sau de biblioteci terțe, trebuie adăugat tools:keep="@layout/my_layout" în resurse. În combinație cu minification, resource shrinking poate reduce dimensiunea APK cu 40-60%.
# proguard-rules.pro — reguli obligatorii
# Gson: păstrează clasele pentru serializare
-keepclassmembers class com.example.** {
<fields>;
}
# Retrofit: păstrează interfețele API
-keep,allowobfuscation interface com.example.api.*
# Room: păstrează DAO și Entity
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }
# Kotlin Coroutines: previne eliminarea Continuation
-keepnames class kotlinx.coroutines.internal.*
# OkHttp: păstrează service loader
-keep class okhttp3.** { *; }
BuildConfig este o clasă Java/Kotlin generată automat care conține constantele definite în defaultConfig, productFlavors și buildTypes. Prin buildConfigField se pot adăuga câmpuri personalizate: buildConfigField "String", "API_URL", '"https://api.example.com"'. BuildConfigField declarat în buildType este disponibil în toate variantele acestui tip. Valorile din buildType suprascriu valorile din productFlavor, care, la rândul lor, suprascriu defaultConfig.
Pentru build-urile debug, este convenabil să setați API_URL pe localhost sau serverul staging, iar pentru release — pe production. BuildConfig.FLAVOR și BuildConfig.BUILD_TYPE sunt, de asemenea, generate automat și conțin numele flavor-ului și build type-ului curent. În cod se poate folosi: if (BuildConfig.DEBUG) { /* loguri */ } — constanta DEBUG este true doar pentru build type-ul debug. BuildConfig.DEBUG este un câmp standard pe care AGP îl adaugă în fiecare BuildConfig.
Resursele pentru Build Type sunt definite prin source set src/<buildType>/res/. De exemplu, src/debug/res/values/strings.xml poate conține textul “Server: Dev”, iar src/release/res/ — “Server: Prod”. Resursele manifestului sunt, de asemenea, suprascrise prin source set: src/debug/AndroidManifest.xml poate include <uses-permission android:name="android.permission.INTERNET" /> doar pentru build-urile debug. Acest lucru este mai curat decât verificarea BuildConfig în cod și funcționează chiar și pentru atribute care nu pot fi setate programatic (de exemplu, 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
}
// Utilizare: clasa principală încarcă Config prin reflection
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
"debug" -> DebugConfig
else -> ReleaseConfig
}
Întrebări frecvente
Da, creați un Build Type personalizat precum debugMinified cu initWith debug și activați minification: debugMinified { initWith debug; minification true }. Acest lucru este util pentru testarea regulilor ProGuard fără a construi versiunea completă release.
Rulați apksigner din Android SDK: apksigner verify --print-certs app-release.apk. Dacă certificatul coincide cu cel încărcat în Google Play Console — semnătura este corectă. Se poate verifica și prin jarsigner pentru formate mai vechi.
matchingFallbacks specifică ce Build Type al bibliotecii să fie utilizat dacă aceasta nu are tipul necesar. De exemplu, dacă aplicația are tipul “staging”, iar biblioteca doar “release”, AGP folosește release pentru bibliotecă. Se specifică ca listă: matchingFallbacks = ["release", "debug"].
În regulile ProGuard, folosiți -keep pentru clasele bibliotecii. De exemplu: -keep class com.some.library.** { *; }. Pentru dezactivarea completă a minification pentru toate bibliotecile, setați -dontobfuscate și -dontoptimize în proguard-rules.pro.
Build Type în sine nu schimbă minSdk sau targetSdk. Dar se poate seta minSdk pentru un Build Type specific: debug { minSdk 21 }. Acest lucru este util pentru build-urile debug — se poate suporta doar API 21+ pentru accelerarea build-ului, iar release să fie construit pe minSdk 26.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și