Build Type dans le développement Android est une configuration Gradle qui détermine comment l'application est compilée : avec ou sans débogage, avec ou sans optimisation de code, et avec quel certificat de signature. Android Gradle Plugin fournit deux Build Types standard — debug et release, et le développeur peut ajouter des types personnalisés, comme staging ou benchmark. Selon Google Android Developers, 2025, une configuration correcte de Build Type réduit la taille de l'APK jusqu'à 60 % grâce à la minification et au resource shrinking. Chaque Build Type est combiné avec Product Flavors pour former un Build Variant.
Points clés
Build Type est un élément de la configuration Gradle dans les projets Android qui décrit les paramètres de compilation et d'empaquetage de l'application. Chaque Build Type est un ensemble nommé d'options : debuggable (activer le débogage), minificationEnabled (activer la compression du code), shrinkResources (activer la compression des ressources), proguardFiles (fichiers de règles ProGuard), signingConfig (certificat de signature) et d'autres. Les Build Types sont déclarés dans le bloc android.buildTypes du fichier build.gradle du module app.
La fonction principale de Build Type est de séparer le workflow de développement (build rapide, journaux détaillés, débogage) de la release de production (code optimisé, taille minimale, sécurité). Le build debug doit compiler en quelques secondes et fournir un maximum d'informations au développeur. Le build release doit être aussi rapide et compact que possible pour les utilisateurs. Build Type est un paramètre d'infrastructure, non lié à la fonctionnalité de l'application.
Android Gradle Plugin crée automatiquement un source set pour chaque Build Type — le répertoire src/<buildType>/ (par exemple, src/debug/, src/release/). Les ressources, le code et les fichiers de manifeste placés dans ce source set s'appliquent uniquement à ce type de build. Par exemple, src/debug/ peut contenir un AndroidManifest.xml avec l'autorisation d'installation depuis ADB, et src/release/ sans. Le source set de Build Type a priorité sur le source set de Product Flavor.
La différence clé : Build Type répond à la question « comment compiler ? », tandis que Product Flavor répond à « quoi compiler ? ». Build Type peut être debug, release, staging. Product Flavor peut être free, paid, enterprise. Build Type ne modifie pas la fonctionnalité de l'application (il n'ajoute ni ne supprime d'écrans), Product Flavor le fait. Build Type peut désactiver le débogueur et activer l'obfuscation, Product Flavor peut modifier applicationId et les ressources. Les deux fonctionnent ensemble : chaque Build Type est combiné avec chaque Product Flavor pour former un Build Variant.
Debug est le Build Type créé par défaut par AGP. Il a debuggable=true, ce qui permet d'attacher le débogueur, de visualiser les logs Log.d et d'utiliser le profileur Android Studio. La minification est désactivée, donc le build est rapide. Dans un build debug, l'applicationId reçoit le suffixe « .debug » (s'il n'est pas redéfini), ce qui permet d'installer la version debug en parallèle de la version release sur le même appareil. Le build debug est signé avec un certificat de debug.keystore, qui est créé automatiquement par Android SDK.
Release est le Build Type pour publier l'application. debuggable=false, minificationEnabled=true (par défaut), shrinkResources=true. Le développeur doit spécifier un signingConfig avec un certificat de production — sinon le build ne sera pas considéré comme un build release. Le build release utilise ProGuard ou R8 pour l'obfuscation, l'optimisation et la compression du code. Android Studio ne peut pas attacher le débogueur à un build release (si debuggable=false). Tous les appels Log.d et Log.v sont supprimés du code lors de la minification si les règles ProGuard appropriées sont configurées.
Important : les builds debug ne testent pas le comportement release. La minification peut modifier le comportement du code — la réflexion, la sérialisation, Gson/SQLite et d'autres bibliothèques nécessitent souvent des règles ProGuard. Par conséquent, compilez et testez toujours un build release avant de publier. Google Play Console et Firebase Test Lab permettent de télécharger des builds release pour des tests automatisés sur des appareils réels avant la publication.
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" }
}
}
}
En plus de debug et release, des Build Types personnalisés peuvent être créés — par exemple staging (environnement intermédiaire) ou benchmark (pour les tests de performance). Un Build Type personnalisé est déclaré dans le bloc buildTypes de la même manière que debug et release. Le nom peut être quelconque, mais il est recommandé d'utiliser des noms sémantiquement clairs en anglais. Pour staging, on définit généralement debuggable=true (pour diagnostiquer les problèmes dans l'environnement staging) et minification=true (pour tester l'obfuscation avant la production).
Un Build Type personnalisé obtient automatiquement un source set correspondant (src/staging/) et génère des tâches comme assembleStaging. AGP n'impose pas de limite sur le nombre de types personnalisés, mais chaque nouveau type multiplie le nombre de Build Variants. La limite pratique est de 4 à 5 Build Types : debug, staging, benchmark, release, et éventuellement debugMinified (debug avec minification activée pour tester les règles ProGuard).
Pour un Build Type personnalisé, vous pouvez hériter de debuggable de debug en utilisant initWith. Le mot-clé initWith copie tous les paramètres du Build Type spécifié, après quoi ils peuvent être redéfinis. C'est pratique pour créer staging basé sur debug : initWith debug + activer en supplément la minification. Sans initWith, vous devriez lister manuellement tous les paramètres du type de base.
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 — pour les bibliothèques qui n'ont pas de type benchmark
// si la bibliothèque n'a que release — AGP l'utilise
SigningConfig détermine quel certificat est utilisé pour signer l'APK ou l'AAB. Android exige que toutes les applications installables soient signées — sans cela, le système n'autorisera pas l'installation. Pour les builds debug, AGP utilise debug.keystore — un certificat préinstallé avec un mot de passe connu généré par Android SDK Tools. Pour les builds release, vous devez créer votre propre certificat via Android Studio (Build → Generate Signed Bundle/APK) ou via la ligne de commande keytool.
Le stockage des clés de signature est un aspect critique de sécurité. Il est recommandé de ne pas stocker les clés release dans le référentiel de code source. Utilisez plutôt un fichier keystore.properties (ajouté à .gitignore), des variables d'environnement CI/CD, ou le stockage chiffré d'Android Studio. Dans CI/CD (GitHub Actions, GitLab CI), les clés de signature sont stockées dans des secrets et transmises à build.gradle via des propriétés système. Exemple : storePassword = System.getenv("KEYSTORE_PASSWORD").
Chaque Build Type peut référencer son propre signingConfig. Pour release — un certificat de production, pour debug — debug.keystore, pour staging — un certificat staging séparé. La configuration de signature affecte directement la possibilité d'installer l'application : si vous signez debug avec debug.keystore et staging avec une clé de production, staging ne peut pas être installé par-dessus la version debug en raison de l'incompatibilité des signatures. L'applicationId doit également différer — utilisez applicationIdSuffix pour cela.
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 est le processus de suppression du code inutilisé et de renommage des classes, méthodes et champs en noms courts. AGP effectue la minification avec ProGuard (ancien) ou R8 (recommandé, intégré à AGP depuis la version 3.4). R8 effectue quatre opérations : shrinking (suppression des classes inutilisées), optimisation (simplification du code), obfuscation (renommage) et preverify (ajout d'informations de compatibilité). Le résultat est un APK plus petit et plus difficile à décompiler.
Les règles de minification sont définies dans des fichiers de règles ProGuard — des fichiers texte avec une syntaxe incluant -keep, -dontwarn, -keepclassmembers. Sans règles, R8 supprimera ou renommera les classes utilisées via la réflexion (Gson, Retrofit, Room, sérialisation Kotlin). Le modèle de projet Android Studio crée un fichier proguard-rules.pro dans lequel les règles pour des bibliothèques spécifiques sont ajoutées. Les bibliothèques peuvent également contenir des règles intégrées — elles sont automatiquement incluses depuis jar/aar.
Shrink resources (shrinkResources=true) supprime les ressources inutilisées de l'APK. R8 détermine d'abord quelles ressources ne sont pas utilisées dans le code (vérifie R.java et les références du manifeste), puis les supprime du build final. Pour les ressources utilisées via getIdentifier() ou par des bibliothèques tierces, vous devez ajouter tools:keep="@layout/my_layout" dans les ressources. Combiné avec la minification, le resource shrinking peut réduire la taille de l'APK de 40 à 60 %.
# proguard-rules.pro — règles obligatoires
# Gson : conserver les classes pour la sérialisation
-keepclassmembers class com.example.** {
<fields>;
}
# Retrofit : conserver les interfaces API
-keep,allowobfuscation interface com.example.api.*
# Room : conserver DAO et Entity
-keep class * extends androidx.room.RoomDatabase
-keep @interface androidx.room.** { *; }
# Kotlin Coroutines : empêcher la suppression de Continuation
-keepnames class kotlinx.coroutines.internal.*
# OkHttp : préserver le service loader
-keep class okhttp3.** { *; }
BuildConfig est une classe Java/Kotlin générée automatiquement qui contient des constantes définies dans defaultConfig, productFlavors et buildTypes. Via buildConfigField, des champs personnalisés peuvent être ajoutés : buildConfigField "String", "API_URL", '"https://api.example.com"'. Un BuildConfigField déclaré dans buildType est disponible dans toutes les variantes de ce type. Les valeurs dans buildType remplacent les valeurs de productFlavor, qui à leur tour remplacent defaultConfig.
Pour les builds debug, il est pratique de définir API_URL sur localhost ou un serveur staging, et pour release — sur la production. BuildConfig.FLAVOR et BuildConfig.BUILD_TYPE sont également générés automatiquement et contiennent le nom du flavor et du build type actuels. Dans le code, vous pouvez utiliser : if (BuildConfig.DEBUG) { /* logs */ } — la constante DEBUG est vraie uniquement pour le build type debug. BuildConfig.DEBUG est un champ standard qu'AGP ajoute à chaque BuildConfig.
Les ressources pour Build Type sont définies via le source set src/<buildType>/res/. Par exemple, src/debug/res/values/strings.xml peut contenir la chaîne « Server: Dev », tandis que src/release/res/ peut contenir « Server: Prod ». Les ressources du manifeste sont également remplacées via le source set : src/debug/AndroidManifest.xml peut inclure <uses-permission android:name="android.permission.INTERNET" /> uniquement pour les builds debug. C'est plus propre que de vérifier BuildConfig dans le code et fonctionne même pour les attributs qui ne peuvent pas être définis par programmation (comme 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
}
// Utilisation : la classe principale charge Config via reflection
fun getConfig(): AppConfig = when (BuildConfig.BUILD_TYPE) {
"debug" -> DebugConfig
else -> ReleaseConfig
}
Questions fréquentes
Oui, créez un Build Type personnalisé comme debugMinified avec initWith debug et activez la minification : debugMinified { initWith debug; minification true }. C'est utile pour tester les règles ProGuard sans compiler une version release complète.
Exécutez apksigner depuis Android SDK : apksigner verify --print-certs app-release.apk. Si le certificat correspond à celui téléchargé dans Google Play Console, la signature est correcte. Vous pouvez également vérifier avec jarsigner pour les anciens formats.
matchingFallbacks spécifie quel Build Type d'une bibliothèque utiliser si elle n'a pas le type requis. Par exemple, si l'application a un type « staging » mais la bibliothèque n'a que « release », AGP utilise release pour la bibliothèque. Il est spécifié comme une liste : matchingFallbacks = ["release", "debug"].
Dans les règles ProGuard, utilisez -keep pour les classes de la bibliothèque. Par exemple : -keep class com.some.library.** { *; }. Pour désactiver complètement la minification pour toutes les bibliothèques, spécifiez -dontobfuscate et -dontoptimize dans proguard-rules.pro.
Build Type lui-même ne modifie ni minSdk ni targetSdk. Cependant, vous pouvez définir minSdk pour un Build Type spécifique : debug { minSdk 21 }. C'est utile pour les builds debug — vous pouvez ne supporter que l'API 21+ pour accélérer le build, tandis que les builds release utilisent minSdk 26.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi