Build-Konfiguration von Groovy zu Kotlin migrieren

Das Android Gradle-Plug-in 4.0 unterstützt die Verwendung von Kotlin in Ihrer Gradle-Build-Konfiguration als Ersatz für Groovy, die Programmiersprache, die traditionell in Gradle-Konfigurationsdateien verwendet wird.

Kotlin wird für das Schreiben von Gradle-Scripts gegenüber Groovy bevorzugt, da Kotlin besser lesbar ist und eine bessere Überprüfung zur Kompilierungszeit sowie IDE-Unterstützung bietet.

Kotlin bietet derzeit im Vergleich zu Groovy eine bessere Einbindung in den Code-Editor von Android Studio. Builds mit Kotlin sind jedoch in der Regel langsamer als Builds mit Groovy. Berücksichtigen Sie daher die Buildleistung, wenn Sie sich für eine Migration entscheiden.

Auf dieser Seite finden Sie grundlegende Informationen zum Konvertieren der Gradle-Build-Dateien Ihrer Android-App von Groovy in Kotlin. Eine umfassendere Anleitung zur Migration finden Sie in der offiziellen Gradle-Dokumentation.

Zeitachse

Ab Android Studio Giraffe verwenden neue Projekte standardmäßig Kotlin DSL (build.gradle.kts) für die Build-Konfiguration. Dies bietet eine bessere Bearbeitung als Groovy DSL (build.gradle) mit Syntaxhervorhebung, Codevervollständigung und Navigation zu Deklarationen. Weitere Informationen finden Sie im Gradle Kotlin DSL Primer.

Gängige Begriffe

Kotlin DSL: Bezieht sich hauptsächlich auf die Kotlin-DSL des Android Gradle-Plug-ins oder gelegentlich auf die untergeordnete Gradle-Kotlin-DSL.

In dieser Migrationsanleitung werden „Kotlin“ und „Kotlin DSL“ synonym verwendet. Ebenso werden „Groovy“ und „Groovy DSL“ synonym verwendet.

Benennung von Scriptdateien

Namen von Skript-Dateiendungen basieren auf der Sprache, in der die Build-Datei geschrieben ist:

  • Gradle-Builddateien, die in Groovy geschrieben sind, haben die Dateiendung .gradle.
  • In Kotlin geschriebene Gradle-Build-Dateien verwenden die Dateiendung .gradle.kts.

Syntax konvertieren

Es gibt einige allgemeine Unterschiede in der Syntax zwischen Groovy und Kotlin. Sie müssen diese Änderungen also in allen Build-Scripts anwenden.

Klammern zu Methodenaufrufen hinzufügen

Mit Groovy können Sie Klammern in Methodenaufrufen weglassen, in Kotlin sind sie jedoch erforderlich. Um Ihre Konfiguration zu migrieren, fügen Sie bei diesen Arten von Methodenaufrufen Klammern hinzu. In diesem Code wird gezeigt, wie eine Einstellung in Groovy konfiguriert wird:

compileSdkVersion 30

Das ist derselbe Code in Kotlin:

compileSdkVersion(30)

= zu Zuweisungsanrufen hinzufügen

In Groovy DSL können Sie den Zuweisungsoperator = beim Zuweisen von Attributen weglassen. Für Kotlin ist dies jedoch erforderlich. Dieser Code zeigt, wie Properties in Groovy zugewiesen werden:

java {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

Dieser Code zeigt, wie Sie Eigenschaften in Kotlin zuweisen:

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

Strings konvertieren

Im Folgenden sind die Stringunterschiede zwischen Groovy und Kotlin aufgeführt:

  • Doppelte Anführungszeichen für Strings: In Groovy können Strings mit einfachen Anführungszeichen definiert werden, in Kotlin sind jedoch doppelte Anführungszeichen erforderlich.
  • Stringinterpolation bei Punktausdrücken: In Groovy können Sie für Stringinterpolationen bei Punktausdrücken nur das Präfix $ verwenden. In Kotlin müssen Sie die Punktausdrücke jedoch in geschweifte Klammern setzen. In Groovy können Sie beispielsweise $project.rootDir verwenden, wie im folgenden Snippet gezeigt:

        myRootDirectory = "$project.rootDir/tools/proguard-rules-debug.pro"
        

    In Kotlin wird mit dem vorherigen Code toString() jedoch für project aufgerufen, nicht für project.rootDir. Wenn Sie den Wert des Stammverzeichnisses abrufen möchten, setzen Sie den Ausdruck ${project.rootDir} in geschweifte Klammern:

        myRootDirectory = "${project.rootDir}/tools/proguard-rules-debug.pro"
        

    Weitere Informationen finden Sie in der Kotlin-Dokumentation unter String-Vorlagen.

Dateiendungen umbenennen

Hängen Sie .kts an jede Build-Datei an, wenn Sie deren Inhalt migrieren. Wählen Sie beispielsweise eine Build-Datei wie die Datei settings.gradle aus. Benennen Sie die Datei in settings.gradle.kts um und konvertieren Sie den Inhalt der Datei in Kotlin. Achten Sie darauf, dass Ihr Projekt nach der Migration jeder Build-Datei noch kompiliert werden kann.

Migrieren Sie zuerst Ihre kleinsten Dateien, sammeln Sie Erfahrung und machen Sie dann weiter. Sie können in einem Projekt sowohl Kotlin- als auch Groovy-Build-Dateien verwenden. Nehmen Sie sich daher die Zeit, die Migration sorgfältig durchzuführen.

Ersetzen Sie def durch val oder var.

Ersetzen Sie def durch val oder var. So können Sie Variablen in Kotlin definieren. Das ist eine Variablendeklaration in Groovy:

def building64Bit = false

Dies ist derselbe Code, der in Kotlin geschrieben wurde:

val building64Bit = false

Boolesche Properties mit is beginnen

In Groovy wird die Ableitungslogik für Properties anhand der Property-Namen verwendet. Bei einem booleschen Attribut foo können die abgeleiteten Methoden getFoo, setFoo oder isFoo sein. Nach der Umwandlung in Kotlin müssen Sie die Attributnamen in die abgeleiteten Methoden ändern, die von Kotlin nicht unterstützt werden. Boolesche Elemente der buildTypes DSL müssen beispielsweise mit is vorangestellt werden. In diesem Code wird gezeigt, wie boolesche Properties in Groovy festgelegt werden:

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            ...
        }
        debug {
            debuggable true
            ...
        }
    ...

Im Folgenden sehen Sie denselben Code in Kotlin. Den Attributen ist is vorangestellt.

android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            ...
        }
        getByName("debug") {
            isDebuggable = true
            ...
        }
    ...

Listen und Karten konvertieren

Listen und Maps werden in Groovy und Kotlin mit unterschiedlicher Syntax definiert. In Groovy wird [] verwendet, während in Kotlin Methoden zum Erstellen von Sammlungen explizit mit listOf oder mapOf aufgerufen werden. Ersetzen Sie bei der Migration [] durch listOf oder mapOf.

So definieren Sie eine Liste in Groovy und Kotlin:

jvmOptions += ["-Xms4000m", "-Xmx4000m", "-XX:+HeapDumpOnOutOfMemoryError</code>"]

Das ist derselbe Code in Kotlin:

jvmOptions += listOf("-Xms4000m", "-Xmx4000m", "-XX:+HeapDumpOnOutOfMemoryError")

So definieren Sie eine Map in Groovy und Kotlin:

def myMap = [key1: 'value1', key2: 'value2']

Das ist derselbe Code in Kotlin:

val myMap = mapOf("key1" to "value1", "key2" to "value2")

Buildtypen konfigurieren

In der Kotlin DSL sind nur die Buildtypen „debug“ und „release“ implizit verfügbar. Alle anderen benutzerdefinierten Build-Typen müssen manuell erstellt werden.

In Groovy können Sie die Buildtypen „debug“, „release“ und bestimmte andere Buildtypen verwenden, ohne sie zuerst erstellen zu müssen. Das folgende Code-Snippet zeigt eine Konfiguration mit den Build-Typen debug, release und benchmark in Groovy.

buildTypes {
 debug {
   ...
 }
 release {
   ...
 }
 benchmark {
   ...
 }
}

Um die entsprechende Konfiguration in Kotlin zu erstellen, müssen Sie den Build-Typ benchmark explizit erstellen.

buildTypes {
 debug {
   ...
 }

 release {
   ...
 }
 register("benchmark") {
    ...
 }
}

Von Buildscript zum Plug-in-Block migrieren

Wenn in Ihrem Build der Block buildscript {} verwendet wird, um dem Projekt Plug-ins hinzuzufügen, sollten Sie ihn durch den Block plugins {} ersetzen. Mit dem Block plugins {} lassen sich Plugins einfacher anwenden und er funktioniert gut mit Versionskatalogen.

Wenn Sie den plugins {}-Block in Ihren Build-Dateien verwenden, erkennt Android Studio den Kontext auch dann, wenn der Build fehlschlägt. Dieser Kontext hilft Ihnen, Fehler in Ihren Kotlin-DSL-Dateien zu beheben, da die Studio IDE Code vervollständigen und andere hilfreiche Vorschläge machen kann.

Plug-in-IDs ermitteln

Im Block buildscript {} werden die Plug-ins dem Build-Classpath mithilfe der Maven-Koordinaten des Plug-ins hinzugefügt, z. B. com.android.tools.build:gradle:7.4.0. Im Block plugins {} werden stattdessen die Plug-in-IDs verwendet.

Bei den meisten Plug-ins ist die Plug-in-ID der String, der verwendet wird, wenn Sie sie mit apply plugin anwenden. Die folgenden Plug-in-IDs sind beispielsweise Teil des Android-Gradle-Plug-ins:

  • com.android.application
  • com.android.library
  • com.android.lint
  • com.android.test

Die vollständige Liste der Plug-ins finden Sie im Maven-Repository von Google.

Auf Kotlin-Plug-ins kann über mehrere Plug-in-IDs verwiesen werden. Wir empfehlen die Verwendung der Namespace-Plug-in-ID und die Refaktorierung von der Kurzschreibweise in die Namespace-Plug-in-ID gemäß der folgenden Tabelle:

Kurzschreibweise Plug-in-IDs Namespace-Plug-in-IDs
kotlin org.jetbrains.kotlin.jvm
kotlin-android org.jetbrains.kotlin.android
kotlin-kapt org.jetbrains.kotlin.kapt
kotlin-parcelize org.jetbrains.kotlin.plugin.parcelize

Sie können auch im Gradle Plugin Portal, im Maven Central Repository und im Maven-Repository von Google nach Plug-ins suchen. Weitere Informationen zur Funktionsweise von Plug-in-IDs finden Sie unter Benutzerdefinierte Gradle-Plug-ins entwickeln.

Refaktorierung ausführen

Führen Sie die folgenden Schritte aus, sobald Sie die IDs der verwendeten Plug-ins kennen:

  1. Wenn Sie noch Repositories für Plug-ins haben, die im Block buildscript {} deklariert sind, verschieben Sie sie stattdessen in die Datei settings.gradle.

  2. Fügen Sie die Plug-ins dem Block plugins {} in der Datei build.gradle auf oberster Ebene hinzu. Hier müssen Sie die ID und die Version des Plug-ins angeben. Wenn das Plug-in nicht auf das Stammprojekt angewendet werden muss, verwenden Sie apply false.

  3. Entfernen Sie die classpath-Einträge aus der übergeordneten Datei build.gradle.kts.

  4. Wenden Sie die Plug-ins an, indem Sie sie dem Block plugins {} in der Datei build.gradle auf Modulebene hinzufügen. Sie müssen hier nur die Plug-in-ID angeben, da die Version vom Stammprojekt übernommen wird.

  5. Entfernen Sie den Aufruf apply plugin für das Plug-in aus der Datei build.gradle auf Modulebene.

In dieser Konfiguration wird beispielsweise der Block buildscript {} verwendet:

// Top-level build.gradle file
buildscript {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:7.4.0")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
        ...
    }
}

// Module-level build.gradle file
apply(plugin: "com.android.application")
apply(plugin: "kotlin-android")

Diese Einrichtung entspricht einer Konfiguration mit dem Block plugins {}:

// Top-level build.gradle file
plugins {
   id 'com.android.application' version '7.4.0' apply false
   id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
   ...
}

// Module-level build.gradle file
plugins {
   id 'com.android.application'
   id 'org.jetbrains.kotlin.android'
   ...
}

// settings.gradle
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

Plug-in-Block konvertieren

Die Anwendung von Plug-ins aus dem plugins {}-Block funktioniert in Groovy und Kotlin ähnlich. Der folgende Code zeigt, wie Plug-ins in Groovy angewendet werden, wenn Sie Versionskataloge verwenden:

// Top-level build.gradle file
plugins {
   alias libs.plugins.android.application apply false
   ...
}

// Module-level build.gradle file
plugins {
   alias libs.plugins.android.application
   ...
}

Im folgenden Code wird gezeigt, wie das in Kotlin funktioniert:

// Top-level build.gradle.kts file
plugins {
   alias(libs.plugins.android.application) apply false
   ...
}

// Module-level build.gradle.kts file
plugins {
   alias(libs.plugins.android.application)
   ...
}

Im folgenden Code wird gezeigt, wie Sie Plugins in Groovy anwenden, wenn Sie keine Versionskataloge verwenden:

// Top-level build.gradle file
plugins {
   id 'com.android.application' version '7.3.0' apply false
   ...
}

// Module-level build.gradle file
plugins {
   id 'com.android.application'
   ...
}

Im folgenden Code wird gezeigt, wie das in Kotlin funktioniert:

// Top-level build.gradle.kts file
plugins {
   id("com.android.application") version "7.3.0" apply false
   ...
}

// Module-level build.gradle.kts file
plugins {
   id("com.android.application")
   ...
}

Weitere Informationen zum Block plugins {} finden Sie in der Gradle-Dokumentation unter Plug-ins anwenden.

Sonstiges

Kotlin-Codebeispiele für andere Funktionen finden Sie auf den folgenden Dokumentationsseiten:

Bekannte Probleme

Derzeit ist es ein bekanntes Problem, dass die Build-Geschwindigkeit mit Kotlin möglicherweise langsamer ist als mit Groovy.

Probleme melden

Eine Anleitung dazu, wie wir die Informationen angeben, die wir zum Erkennen eines Problems benötigen, finden Sie unter Details zu Build-Tools und Gradle-Fehlern. Melden Sie dann den Fehler über die öffentliche Problemverfolgung von Google.

Weitere Ressourcen

Ein funktionierendes Beispiel für Gradle-Builddateien, die mit Kotlin geschrieben wurden, finden Sie in der Now In Android-Beispiel-App auf GitHub.