Migracja konfiguracji kompilacji z Groovy do Kotlin

Wtyczka Androida do obsługi Gradle w wersji 4.0 obsługuje teraz używanie Kotlina w konfiguracji kompilacji Gradle jako zamiennik Groovy, języka programowania używanego tradycyjnie w plikach konfiguracyjnych Gradle.

Kotlin jest preferowanym językiem do pisania skryptów Gradle, ponieważ jest bardziej czytelny i oferuje lepszą obsługę IDE oraz lepszą kontrolę w czasie kompilacji.

Chociaż Kotlin obecnie oferuje lepszą integrację z edytorem kodu Android Studio niż Groovy, kompilacje korzystające z Groovy są zwykle wolniejsze od tych utworzonych przy użyciu Groovy, dlatego przy podejmowaniu decyzji o migracji weź pod uwagę wydajność kompilacji.

Ta strona zawiera podstawowe informacje o konwertowaniu plików kompilacji Gradle aplikacji na Androida z Groovy do Kotlin. Bardziej kompleksowy przewodnik po migracji znajdziesz w oficjalnej dokumentacji Gradle.

Oś czasu

Począwszy od Android Studio Giraffe, nowe projekty domyślnie konfigurują kompilacje z użyciem DSL Kotlin (build.gradle.kts). Zapewnia to lepsze wrażenia podczas edycji niż w przypadku Groovy DSL (build.gradle) dzięki wyróżnianiu składni, autouzupełnianiu kodu i przechodzeniu do deklaracji. Więcej informacji znajdziesz w artykule Wprowadzenie do Gradle Kotlin DSL.

Często używane terminy

Kotlin DSL: odnosi się głównie do wtyczki Androida do obsługi Gradle Kotlin lub, w niektórych przypadkach, do odpowiedniego DSL Gradle Kotlin.

W tym przewodniku po migracji nazwy „Kotlin” i „Kotlin DSL” są używane wymiennie. Nazwy „Groovy” i „Groovy DSL” są stosowane wymiennie.

Nazwy plików skryptów

Nazwy rozszerzeń plików skryptu zależą od języka, w którym napisano plik kompilacji:

  • Pliki kompilacji Gradle napisane w Groovy mają rozszerzenie nazwy pliku .gradle.
  • Pliki kompilacji Gradle napisane w Kotlin mają rozszerzenie nazwy pliku .gradle.kts.

Konwertuj składnię

Między Groovy a Kotlinem występują pewne ogólne różnice w składni, więc musisz zastosować te zmiany w swoich skryptach kompilacji.

Dodawanie nawiasów do wywołań metod

Groovy pozwala pomijać nawiasy w wywołaniach metod, podczas gdy Kotlin ich wymaga. Aby przenieść konfigurację, dodaj nawiasy do tego rodzaju wywołań metod. Ten kod pokazuje, jak skonfigurować ustawienie w Groovy:

compileSdkVersion 30

Ten sam kod jest zapisany w kotlinie:

compileSdkVersion(30)

Dodawanie = do wywołań projektów

W przypadku Groovy DSL można pominąć operator przypisania = podczas przypisywania właściwości, podczas gdy Kotlin tego wymaga. Ten kod pokazuje, jak przypisać właściwości w Groovy:

java {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

Ten kod pokazuje, jak przypisywać właściwości w Kotlinie:

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

Konwertuj ciągi znaków

Groovy i Kotlin różnią się strunkami to:

  • Podwójne cudzysłowy na ciągach: Groovy umożliwia definiowanie ciągów znaków za pomocą cudzysłowów pojedynczych, a Kotlin wymaga cudzysłowów podwójnych.
  • Interpolacja ciągu znaków w wyrażeniach z kropkami: w Groovy możesz użyć tylko prefiksu $ do interpolacji ciągu znaków w wyrażeniach z kropkami, ale Kotlin wymaga nawiasów klamrowych wokół takich wyrażeń. Na przykład w Groovy możesz użyć funkcji $project.rootDir, jak w tym fragmencie kodu:

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

    W Kotlinie jednak poprzedzający kod wywołuje funkcję toString() w obiekcie project, a nie project.rootDir. Aby uzyskać wartość katalogu głównego, umieść wyrażenie ${project.rootDir} w nawiasach klamrowych:

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

    Więcej informacji znajdziesz w opisie szablonów ciągów znaków w dokumentacji Kotlin.

Zmiana rozszerzeń plików

Dodaj .kts do każdego pliku kompilacji podczas migracji jego zawartości. Wybierz na przykład plik kompilacji, na przykład plik settings.gradle. Zmień nazwę pliku na settings.gradle.kts, a jego zawartość przekonwertuj na Kotlin. Upewnij się, że projekt nadal się kompiluje po migracji każdego pliku kompilacji.

Zacznij od migracji najmniejszych plików, zyskaj doświadczenie i dopiero potem działaj. W projekcie możesz mieć mieszankę plików kompilacji Kotlin i Groovy, więc poświęć trochę czasu na ostrożne przeprowadzenie tej zmiany.

Zamień def na val lub var

Zastąp def wartością val lub var, która jest sposobem definiowania zmiennych w Kotlinie. To jest deklaracja zmiennej w Groovy:

def building64Bit = false

Oto ten sam kod napisany w języku Kotlin:

val building64Bit = false

Prefiksowanie właściwości logicznych prefiksem is

Groovy używa logiki dedukcji właściwości na podstawie nazw właściwości. W przypadku właściwości logicznej foo jej metodami dedukcji mogą być getFoo, setFoo lub isFoo. Dlatego po przekonwertowaniu na Kotlin musisz zmienić nazwy właściwości na metody dedukcji, które nie są obsługiwane przez Kotlin. Na przykład w przypadku elementów logicznych DSL buildTypes musisz dodać prefiks is. Ten kod pokazuje, jak ustawiać właściwości logiczne w Groovy:

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

Poniżej znajduje się ten sam kod w języku Kotlin. Pamiętaj, że właściwości są poprzedzone ciągiem is.

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

Konwertowanie list i map

Listy i mapy w Groovy i Kotlin są zdefiniowane przy użyciu innej składni. Groovy używa metody [], a Kotlin bezpośrednio wywołuje metody tworzenia kolekcji za pomocą listOf lub mapOf. Podczas migracji pamiętaj, aby zastąpić [] elementem listOf lub mapOf.

Oto jak zdefiniować listę w Groovy i w Kotlinie:

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

Ten sam kod jest zapisany w kotlinie:

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

Oto jak zdefiniować mapę w Groovym i Kotlinie:

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

Ten sam kod jest zapisany w kotlinie:

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

Konfigurowanie typów kompilacji

W Kotlin DSL domyślnie dostępne są tylko typy kompilacji debugowania i wersji. Pozostałe niestandardowe typy kompilacji należy tworzyć ręcznie.

W Groovy możesz używać kompilacji do debugowania, wersji i niektórych innych typów kompilacji bez ich wcześniejszego tworzenia. Ten fragment kodu pokazuje konfigurację z typami kompilacji debug, releasebenchmark w programie Groovy.

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

Aby utworzyć odpowiednią konfigurację w Kotlinie, musisz jawnie utworzyć typ kompilacji benchmark.

buildTypes {
 debug {
   ...
 }

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

Migracja z buildscript do bloku pluginów

Jeśli Twoja kompilacja używa bloku buildscript {} do dodawania wtyczek do projektu, musisz przerefaktoryzować kod, aby zamiast niego używać bloku plugins {}. Blok plugins {} ułatwia stosowanie wtyczek i dobrze działa z katalogami wersji.

Jeśli w plikach kompilacji używasz bloku plugins {}, Android Studio zna kontekst nawet wtedy, gdy kompilacja się nie powiedzie. Ten kontekst pomaga w wprowadzaniu poprawek do plików Kotlin DSL, ponieważ umożliwia Studio IDE przeprowadzanie funkcji autouzupełniania kodu i podawanie innych przydatnych sugestii.

Znajdowanie identyfikatorów wtyczek

Blok buildscript {} dodaje wtyczki do ścieżki klasyfikacji kompilacji za pomocą koordynat Maven wtyczki, np. com.android.tools.build:gradle:7.4.0, natomiast blok plugins {} używa identyfikatorów wtyczek.

W przypadku większości wtyczek identyfikator wtyczki to ciąg znaków używany podczas ich stosowania za pomocą funkcji apply plugin. Na przykład te identyfikatory wtyczek są częścią wtyczki Androida do obsługi Gradle:

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

Pełną listę wtyczek znajdziesz w repozytorium Google Maven.

Do wtyczek Kotlin może odwoływać się wiele identyfikatorów wtyczek. Zalecamy użycie identyfikatora wtyczki z przestrzenią nazw i refaktoryzację ze skróconego identyfikatora wtyczki z przestrzenią nazw na identyfikator wtyczki z przestrzenią nazw. W tym celu użyj tej tabeli:

Identyfikatory skrótów w pluginach Identyfikatory wtyczek z przestrzenią nazw
kotlin org.jetbrains.kotlin.jvm
kotlin-android org.jetbrains.kotlin.android
kotlin-kapt org.jetbrains.kotlin.kapt
kotlin-parcelize org.jetbrains.kotlin.plugin.parcelize

Wtyczki możesz też wyszukiwać w portalu wtyczek Gradle, centralnym repozytorium Mavenrepozytorium Google Maven. Aby dowiedzieć się więcej o tym, jak działają identyfikatory wtyczek, przeczytaj artykuł Tworzenie niestandardowych wtyczek Gradle.

Przeprowadź refaktoryzację.

Po zapoznaniu się z identyfikatorami używanych wtyczek wykonaj te czynności:

  1. Jeśli nadal masz repozytoria wtyczek zadeklarowane w bloku buildscript {}, przenieś je do pliku settings.gradle.

  2. Dodaj wtyczki do bloku plugins {} w pliku najwyższego poziomu build.gradle. Tutaj musisz podać identyfikator i wersję wtyczki. Jeśli wtyczka nie musi być stosowana w projekcie głównym, użyj apply false.

  3. Usuń wpisy classpath z pliku build.gradle.kts najwyższego poziomu.

  4. Zastosuj wtyczki, dodając je do bloku plugins {} w pliku build.gradle na poziomie modułu. Wystarczy, że podasz w tym miejscu identyfikator wtyczki, ponieważ wersja jest dziedziczona z projektu głównego.

  5. Usuń wywołanie apply plugin w pliku build.gradle na poziomie modułu.

W tym przykładzie użyto bloku buildscript {}:

// 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")

Jest to równoważna konfiguracja z wykorzystaniem bloku 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()
    }
}

Konwertowanie bloku wtyczek

Stosowanie wtyczek z bloku plugins {} jest podobne w Groovy i Kotlin. Ten kod pokazuje, jak stosować wtyczki w Groovy, gdy używasz katalogów wersji:

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

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

Poniższy kod pokazuje, jak zrobić to samo w Kotlin:

// 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)
   ...
}

Ten kod pokazuje, jak stosować wtyczki w Groovy, gdy nie używasz katalogów wersji:

// 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'
   ...
}

Poniższy kod pokazuje, jak zrobić to samo w Kotlin:

// 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")
   ...
}

Więcej informacji o bloku plugins {} znajdziesz w artykule o stosowaniu wtyczek w dokumentacji Gradle.

Różne

Przykładowe fragmenty kodu Kotlin dotyczące innych funkcji znajdziesz na tych stronach dokumentacji:

Znane problemy

Obecnie znanym problemem jest to, że szybkość kompilacji może być w przypadku Kotlina wolniejsza niż w przypadku Groovy.

Jak zgłaszać problemy

Instrukcje przekazywania informacji potrzebnych do klasyfikacji problemu znajdziesz w artykule Szczegóły narzędzi do kompilacji i błędów Gradle. Następnie zgłoś błąd za pomocą publicznego narzędzia do rejestrowania błędów Google.

Więcej materiałów

Praktyczny przykład plików kompilacji Gradle zapisanych w Kotlin znajdziesz w przykładowej aplikacji Now In Android na GitHubie.