By: Jonas Heder
2016-09-06
Introduktion till Gradle
Jag gick nyligen online-kursen Gradle for Android and Java hos Udacity. Den bestod av en stor mängd kortare videor blandat med övningar. Vad är Gradle? Här är en kort introduktion.
**Komplicerade byggprocesser**
Inom systemutveckling är det sällsynt att det som byggs enbart består av några få filer. Oftast är det en större mängd filer av olika slag och beroenden till tredjepartsbibliotek som ska paketeras ihop för att producera en färdig applikation på den valda plattformen. Exempelvis inom Android kan processen se ut så här:
– Hämta tredjepartsbibliotek (dependency-hantering)
– Kompilera Java-kod till byte-kod
– Konvertera byte-koden till DEX-format (formatet som körs på Androids egna Dalvik Virtual Machine)
– Hantera resursfiler (t.ex. XML-baserade layout-filer och bilder)
– Paketera allt till en körbar app (APK-fil)
– Kryptografisk signering (för uppladdning till Google Play)
För att därutöver ha en god kvalitet kanske även följande punkter körs:
– Tester
– Generera testrapport
– Generera dokumentation
Dessutom kanske det behövs både debug- och release-versioner där både gratis- och betalversioner av appen ingår. Att genomföra denna process manuellt varje gång en ny version har skapats skulle vara väldigt tidsödande och även riskabelt, p.g.a. fel kopplade till den mänskliga faktorn. Dessutom är det i många fall nödvändigt att snabbt kunna få ut en ny version på marknaden, exempelvis för att inte hamna efter konkurrensmässigt eller för att snabbare kunna rätta en allvarlig bugg.
**Gradle**
Gradle är ett automatiseringsverktyg som underlättar ovanstående process. I Gradle definieras processen genom att koppla ihop ett antal delsteg. Ett visst steg kan exempelvis vara “kopiera fil x till plats y”. Processens delsteg kopplas ihop genom att de har olika beroenden till varandra, exempelvis att delsteg B inte kan börja förrän delsteg A körts färdigt. Gradle organiserar sedan ihop delstegen beroende på hur de relaterar till varandra. Verktyget håller reda på vad varje delsteg förväntas få in och producera och kan därigenom bedöma om ett delsteg behöver köras igen eller inte. Detta sparar tid då inte alla föregående delsteg behöver köras om ifall ett visst delsteg fallerat (så kallade inkrementella byggen).
Gradle har liknande syfte som det äldre verktyget Maven. Medan Maven är XML-baserat så har Gradle ett eget Groovy-baserat språk. Språket är kompatibelt med både Groovy och Java – dessa kan blandas i samma Gradle-fil. Dock brukar Gradle-filerna till stor del vara deklarativa för att tydligare åskådliggöra hur ens process är konfigurerad. Om det behövs mer komplicerad logik för ett delsteg i ens process så görs detta oftast i form av ett plugin. Gradle-plugin kan skrivas i valfritt JVM-kompatibelt språk, t.ex. Java, Scala, Groovy eller Kotlin.
Numer är Gradle det officiella automatiseringsverktyget inom Android-utveckling, då det integrerats i det IntelliJ-baserade Android Studio. Med finns även ett Android-specifikt Gradle-plugin där processen för att paketera grundläggande Android-appar är definierad. Denna process kan sedan skräddarsys efter behov.
Gradle är kompatibelt med existerande Maven-artefakter och kan därigenom återanvända hela det ekosystem som byggts upp under många års tid i olika repositories, vilket är en stor fördel.
**Installation**
Gradle kan köras antingen globalt eller isolerat i ett enskilt projekt. Om det görs isolerat i ett projekt skapas en lokal s.k. Gradle Wrapper som laddar ner rätt version av Gradle till det aktuella projektet. Denna Gradle Wrapper kan sedan med fördel versionshanteras för att säkerställa att alla medlemmar i projektet använder samma Gradle-version. När Gradle är installerat definierar man själva byggprocessen i en Gradle-fil (build.gradle) i projektet.
**Exempel**
Följande är ett enkelt exempel på en definition av två delsteg i en build.gradle-fil. Ett delsteg skriver först ut en loggtext, varefter ett annat delsteg kopierar filerna i en mapp till en annan mapp. Det andra delsteget körs först efter att det första körts färdigt.
“`
task foo { // nytt delsteg foo
println ‘hello’
finalizedBy ‘bar’ // aktivera delsteget bar när detta delsteg är färdigt
}
task bar(type: Copy) { // nytt delsteg bar som implementerar den fördefinierade typen Copy
from ‘src’ // parameter till from som tillhör typen Copy
into ‘build’ // parameter till into som tillhör typen Copy
}
“`
Därefter kan processen startas med delsteget foo genom att i terminalen skriva “gradle foo”. I loggningen syns det vilka delsteg som redan är färdiga och vilka som återstår eller har fallerat.
Läs mer om Gradle här.
/ Jonas Heder, Java- och Android-utvecklare på Dynabyte