Het bouwen van Gradle-plugins is niet nieuw, en Kotlin is niet nieuw, en Android is niet nieuw. Op dezelfde manier is het bouwen van Gradle-plugins in Kotlin niet nieuw, net zomin als het bouwen van Gradle-plugins voor Android-apps. Maar het bouwen van Gradle plugins, in Kotlin, voor Android? Nou, er is niet echt veel informatie over te vinden.
Voordat we beginnen, zal ik even vermelden dat het schrijven van Android Gradle plugins, in veel opzichten, veel gemakkelijker is als je in Groovy schrijft. Maar wat we wilden doen was gemakkelijk, we zouden er niet over praten. Dus laten we ons gewoon aan het plan houden.
Er zijn dus veel bronnen over het bouwen van plugins in Kotlin, en veel zijn geweldig, dus als je net vanaf nul begint, ga dan eerst even googelen voordat je verder gaat, want we gaan nu meteen naar het goede spul: Hoe krijg je toegang tot de Android troep in je Kotlin Gradle plugin?
Allereerst, wat bedoelen we met “Android junk?” Nou, wanneer je gradle-builscript wordt uitgevoerd om je Android-app te bouwen, voegt de android-plugin een aantal taken toe aan je build, en je configureert deze taken in de android-sluiting die de plugin gebruikt voor configuratie. Je android closure in je build.gradle bestand zou er ongeveer zo uit kunnen zien:
En als je je eigen plugin maakt, wil je misschien wel weten wat er in die closure staat, of andere dingen die de AGP doet. Voor groovy is dit allemaal vrij eenvoudig, omdat je voor groovy niets expliciet hoeft te importeren. Maar met Kotlin, kun je daar niet mee wegkomen. Dus, het eerste wat je moet doen, is een afhankelijkheid toevoegen in je Gradle plugin’s build.gradle bestand op de Android Gradle Plugin. Dus, in je plugin’s build.gradle script, heb je nodig:
dependencies {
implementation gradleApi()
implementation 'com.squareup:javapoet:1.10.0'
implementation 'com.squareup:kotlinpoet:1.0.0-RC1'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compileOnly("com.android.tools.build:gradle:3.6.3")
}
De sleutel hier is de laatste regel. We gebruiken compileOnly, omdat, tijdens runtime, deze afhankelijkheid zal worden geleverd door het build.script van de Android applicatie die je plugin toepast, in zijn build script. Alles wat we nodig hebben is dat je plugin zich bewust is van de AGP, zodat we gebruik kunnen maken van de API’s die het biedt.
The Kotlin Part
Nu dat de afhankelijkheid is opgenomen, kan onze plugin eindelijk toegang krijgen tot die zoete Android troep:
Als je toegang wilt krijgen tot de android closure in je plugin, moet je eerst een instantie van de build’s AppExtension krijgen. Doe dit met de volgende regel:
val appExtension = project.extensions.findByType(AppExtension::class.java)
Als je eenmaal de AppExtension-instantie hebt, kun je allerlei dingen doen, zoals de app-varianten ondervragen, taken toevoegen aan de Android-bouwlevenscyclus met de functie dependsOn(), en zelfs, zoals in het bovenstaande voorbeeld wordt gesuggereerd, nieuwe bronbestanden genereren en deze in je project compileren.