Gradle is een buildsysteem dat de compilatie, het testen en het verpakken van Android-applicaties automatiseert. In tegenstelling tot Apache Ant of Maven ondersteunt het incrementeel bouwen en cachen van resultaten. Lees meer over de mogelijkheden in de officiële Gradle-documentatie. Sinds 2013 wordt het hulpmiddel gebruikt als het standaard buildsysteem voor Android-projecten in Android Studio.
Belangrijkste punten
Gradle is een open-source buildautomatiseringstool geschreven in Java, die op de JVM draait. Het neemt broncode, afhankelijkheden en bronnen als invoer en levert een kant-en-klare applicatie — APK of AAB voor Android — als uitvoer. Aan de basis van Gradle ligt het concept van een gerichte acyclische taakgraaf (DAG), waarbij elke taak een atomaire werkeenheid is en de verbindingen ertussen de uitvoervolgorde bepalen. In tegenstelling tot Make of Ant vereist Gradle geen handmatige beschrijving van de stappenreeks: het is voldoende om afhankelijkheden tussen taken te declareren en het systeem zal zelf de optimale volgorde bepalen. Deze benadering maakt Gradle flexibel en schaalbaar voor projecten van elke omvang.
Het systeem gebruikt drie uitvoeringsfasen: initialisatie (bepalen van deelnemende projecten), configuratie (opbouwen van de taakgraaf) en uitvoering (starten van taken in de juiste volgorde). De configuratiefase is het belangrijkste verschil van Gradle: het hele buildscript wordt uitgevoerd voordat de taken worden gestart, waardoor de graaf dynamisch kan worden aangepast aan de omstandigheden. Dit biedt de mogelijkheid om bijvoorbeeld alleen voor bepaalde buildvarianten taken toe te voegen zonder code te dupliceren. De builder is geschreven in Groovy, maar configuratiebestanden ondersteunen twee talen: Groovy DSL en Kotlin DSL.
De Android-plugin voor Gradle — com.android.application en com.android.library — voegen taken toe aan het project voor het werken met Android-hulpmiddelen. Wanneer een ontwikkelaar de build start, voert Gradle tientallen taken na elkaar uit: compilatie van Kotlin en Java via javac of kotlinc, verwerking van bronnen via AAPT2, generatie van R.java, compilatie van bytecode naar DEX via D8 of R8, ondertekening en zippen van APK. Elke taak controleert of de invoergegevens zijn gewijzigd, en zo niet — gebruikt het gecachte resultaat. Dit mechanisme heet incrementeel bouwen en versnelt de hercompilatie met 60–80% in vergelijking met een volledige herbouw.
De configuratie van de Android-module wordt ingesteld in het android-blok van het build.gradle.kts-bestand. Binnen het blok worden compileSdk, minSdk, targetSdk, applicatieversie, handtekeningen en andere parameters gedefinieerd. Gradle maakt automatisch voor elke module meerdere buildvarianten — een combinatie van type (release, debug) en flavour. Voor een module met twee flavours en twee types genereert Gradle bijvoorbeeld vier taken: assembleDemoDebug, assembleDemoRelease, assembleFullDebug, assembleFullRelease. Al deze taken kunnen afzonderlijk worden uitgevoerd of met één opdracht voor alle varianten tegelijk worden gestart.
Elk Android-project bevat twee configuratieniveaus: root build.gradle.kts (instellingen voor alle modules) en module build.gradle.kts (instellingen voor een specifieke module). In het rootbestand worden plugins gedeclareerd zonder toepassing, repositories en gemeenschappelijke variabelen. In het modulebestand worden plugins toegepast op de specifieke module en worden de buildparameters geconfigureerd. Deze benadering maakt het mogelijk om versies van afhankelijkheden centraal te beheren via een versiecatalogus of ext-blok.
@Suppress("UnstableApiUsage")
plugins {
id("com.android.application") version "8.2.2"
id("org.jetbrains.kotlin.android") version "1.9.22"
}
android {
namespace = "com.example.myapp"
compileSdk = 34
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
}Het dependencies-blok is een ander kritiek element van build.gradle.kts. Hierin worden de bibliotheken, modules en bestandsafhankelijkheden vermeld die de applicatie nodig heeft. Gradle ondersteunt meerdere afhankelijkheidsconfiguraties: implementation (alleen toegankelijk voor de huidige module), api (ook toegankelijk voor afhankelijke modules), testImplementation (alleen voor tests), androidTestImplementation (voor instrumentele tests) en compileOnly (alleen tijdens compilatie). Elke configuratie beheert de zichtbaarheid van klassen in de afhankelijkheidsgraaf, wat invloed heeft op de buildtijd en de grootte van het uiteindelijke artefact.
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.8.2")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
}Build variant — een combinatie van build type en product flavour die een versie van de applicatie definieert met unieke instellingen, code en bronnen. Build type (het buildtype) bepaalt de verpakkingsparameters: debug (met debugging en achtervoegsel .debug) of release (met obfuscatie en handtekening). Product flavour (de productsmaak) bepaalt de functionele varianten: bijvoorbeeld demo (beperkte versie) en full (volledige versie met extra functies). Gradle genereert automatisch taken voor elke combinatie, waardoor alle versies met één opdracht kunnen worden gebouwd.
android {
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
debug {
applicationIdSuffix = ".debug"
}
}
flavorDimensions += "version"
productFlavors {
create("demo") {
dimension = "version"
applicationIdSuffix = ".demo"
}
create("full") {
dimension = "version"
applicationIdSuffix = ".full"
}
}
}Elke build variant heeft een aparte source set. Gradle gebruikt de mappen src/demo/release, src/full/debug en andere, waar unieke bronnen, manifests en broncode voor de specifieke variant worden opgeslagen. Gemeenschappelijke code blijft in src/main. Deze benadering maakt het mogelijk om de hoofdlogica te hergebruiken en alleen de verschillende delen te vervangen: strings, pictogrammen, API-eindpunten of configuratiebestanden. Source set kan elke bron uit main overschrijven: manifest, drawable, values of zelfs Kotlin-klassen. Bij het bouwen van een specifieke variant combineert Gradle bestanden uit main en de bijbehorende source set, waarbij bestanden uit de variant prioriteit hebben.
Het ecosysteem van Gradle-plugins bestrijkt alle fasen van de ontwikkeling van Android-applicaties. Officiële plugins van Google omvatten com.android.application (voor de applicatiemodule), com.android.library (voor de bibliotheekmodule), com.android.test (voor testmodules) en Kotlin-plugins van JetBrains. Plugins voegen nieuwe taken toe aan het project, breiden DSL uit met nieuwe configuratieblokken en koppelen extra hulpmiddelen aan. Zonder de plugin com.android.application kan het project geen APK bouwen: deze plugin registreert alle Android-specifieke taken en verbindt ze in de buildgraaf.
Plugins van derden lossen meer specifieke taken op. Google Services (com.google.gms.google-services) integreert Firebase en Google Play Services en voegt automatisch google-services.json toe aan de build. Hilt (dagger.hilt.android.plugin) genereert code voor het injecteren van afhankelijkheden tijdens de compilatie. Safe Args (androidx.navigation.safeargs.kotlin) maakt type-veilige klassen voor navigatie tussen fragmenten. Elke plugin wordt in de root build.gradle.kts verbonden via het plugins-blok en vereist meestal minimale configuratie. Gradle lost automatisch transitieve afhankelijkheden tussen plugins op en garandeert versiecompatibiliteit via Bom-bestanden en de versiecatalogus.
Een taak (task) is een atomaire werkeenheid in Gradle. Elke taak heeft invoergegevens, uitvoergegevens en een actie. Ingebouwde taken voor Android omvatten assemble (bouwen van alle varianten), lint (codecontrolle), test (uitvoeren van unittesten) en clean (opschonen van tijdelijke bestanden). De ontwikkelaar kan eigen taken toevoegen met Groovy of Kotlin DSL. Aangepaste taken zijn handig voor het automatiseren van routinematige bewerkingen: het genereren van rapporten, kopiëren van artefacten, implementeren op testapparaten of integratie met CI-systemen.
tasks.register("printBuildInfo") {
description = "Toont informatie over de build"
group = "custom"
doLast {
println("Build variant: ${project.name}")
println("Version: ${android.defaultConfig.versionName}")
}
}Elke taak kan afhankelijk zijn van andere taken via het dependsOn-mechanisme. Als taak A afhankelijk is van taak B, garandeert Gradle dat B wordt uitgevoerd vóór A. Het systeem vereist geen handmatige opgave van de volgorde voor elk paar — het is voldoende om afhankelijkheden te declareren en Gradle bouwt een gerichte graaf, geoptimaliseerd voor parallelle uitvoering van onafhankelijke taken. De ingebouwde taken van de Android-plugin zijn al met elkaar verbonden: lint is afhankelijk van compilatie, test is afhankelijk van assemble, assembleDebug is afhankelijk van compileDebugKotlin. De ontwikkelaar kan zijn eigen taken in elk knooppunt van de graaf plaatsen met dependsOn, mustRunAfter of shouldRunAfter.
Een van de veelvoorkomende problemen is versieconflict van afhankelijkheden, wanneer twee bibliotheken verschillende versies van dezelfde transitieve afhankelijkheid vereisen. Gradle meldt de conflictfout, maar biedt niet altijd een automatische oplossing. Gebruik voor diagnose de opdracht ./gradlew :app:dependencies, die de volledige afhankelijkheidsboom weergeeft. Het wordt aanbevolen om de versie van de conflicterende bibliotheek geforceerd op te geven via het resolutionStrategy-blok. Een ander veelvoorkomend scenario is traag bouwen door het ontbreken van incrementele verwerking. Controleer of alle plugins zijn bijgewerkt, Gradle Daemon is ingeschakeld (org.gradle.daemon=true) en in gradle.properties voldoende geheugen is ingesteld: org.gradle.jvmargs=-Xmx4096m.
Problemen met caching ontstaan na het bijwerken van afhankelijkheden: Gradle kan verouderde cache gebruiken en de build eindigt met een fout. Oplossing — voer de build uit met de vlag --refresh-dependencies of maak de cache handmatig leeg via ./gradlew cleanBuildCache. De derde meest voorkomende fout is incompatibiliteit van Android Gradle Plugin (AGP) en Gradle-versies. Elke AGP-versie vereist een bepaalde minimale Gradle-versie. De compatibiliteitstabel wordt gepubliceerd op developer.android.com. Als de versies incompatibel zijn, eindigt Gradle met een fout in de configuratiefase met een melding over de minimaal vereiste versie. Controleer altijd of de versie van de Gradle wrapper voldoet aan de AGP-vereisten.
Veelgestelde vragen
Gradle is een automatiseringsprogramma voor het bouwen van projecten. Het neemt je broncode in Kotlin of Java, sluit bibliotheken van internet aan, compileert alles naar bytecode en verpakt het in APK. Het draait op de JVM en gebruikt declaratieve scripts in plaats van handmatige instructies. De ontwikkelaar hoeft alleen de regels te beschrijven en de rest doet Gradle zelf.
Build.gradle wordt geschreven in Groovy — een dynamische taal met flexibele syntax en minder striktheid. Build.gradle.kts gebruikt Kotlin DSL: sterke typering, automatisch aanvullen in Android Studio en foutcontrole tijdens compilatie. Google raadt Kotlin DSL aan voor alle nieuwe projecten. Groovy-bestanden zijn gemakkelijker te migreren, maar Kotlin-bestanden zijn betrouwbaarder in onderhoud.
Schakel Gradle Daemon (org.gradle.daemon=true) en parallel bouwen (org.gradle.parallel=true) in. Verhoog het JVM-geheugen naar 4–8 GB via org.gradle.jvmargs. Gebruik configuratie op aanvraag (org.gradle.configureondemand=true). Configureer voor Android-projecten taakcaching en bouw alleen voor de benodigde ABI. Gebruik in Android Studio de Build Analyzer om knelpunten te vinden.
Build variant — is een combinatie van build type (bijvoorbeeld debug of release) en product flavour (bijvoorbeeld demo of full). Elke variant kan zijn eigen pakketnaam, versie, bronnen en bronbestanden hebben. Gradle maakt automatisch een aparte buildtaak voor elke variant. Dit maakt het mogelijk om meerdere versies van de app vanuit één project te bouwen.
Afhankelijkheden worden toegevoegd in het dependencies-blok van het build.gradle.kts-bestand. Het formaat is: configuration("group:artifact:version"). Bijvoorbeeld implementation("androidx.core:core-ktx:1.12.0"). Gebruik voor tests testImplementation, voor instrumentele tests androidTestImplementation. Het is handig om versies in een aparte versiecatalogus (version catalog) te plaatsen via het bestand libs.versions.toml.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook