Migracja konfiguracji kompilacji z Groovy do Kotlin

Wtyczka Androida do obsługi Gradle w wersji 4.0 umożliwia korzystanie z języka Kotlin w konfiguracji kompilacji Gradle jako zamiennika języka programowania Groovy, który tradycyjnie był używany w plikach konfiguracji Gradle.

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

Kotlin oferuje obecnie lepszą integrację w edytorze kodu w Android Studio niż Groovy, ale kompilacje z użyciem Kotlina są zwykle wolniejsze niż kompilacje z użyciem Groovy. Dlatego przy podejmowaniu decyzji o przeprowadzeniu migracji należy wziąć pod uwagę wydajność kompilacji.

Na tej stronie znajdziesz podstawowe informacje o konwertowaniu plików Gradle na potrzeby kompilacji aplikacji na Androida z Groovy na Kotlin. Pełniejszy przewodnik po migracji znajdziesz w oficjalnej dokumentacji Gradle.

Oś czasu

Począwszy od Android Studio Giraffe nowe projekty domyślnie korzystają z języka Kotlin DSL (build.gradle.kts) do konfiguracji kompilacji. 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 podręczniku Gradle Kotlin DSL.

Często używane terminy

Kotlin DSL: odnosi się głównie do wtyczki Android Gradle Kotlin DSL lub czasami do podstawowego Kotlin DSL w Gradle.

W tym przewodniku po migracji terminy „Kotlin” i „Kotlin DSL” są używane wymiennie. Podobnie terminy „Groovy” i „Groovy DSL” są używane zamiennie.

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 języku Groovy mają rozszerzenie .gradle.
  • Pliki kompilacji Gradle napisane w Kotlinie używają rozszerzenia nazwy pliku .gradle.kts.

Konwertowanie składni

Istnieje kilka ogólnych różnic w składni między Groovy a Kotlinem, 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 typu wywołań metod. Ten kod pokazuje, jak skonfigurować ustawienie w Groovy:

compileSdkVersion 30

Oto ten sam kod napisany w języku Kotlin:

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
}

Konwertowanie ciągów

Oto różnice między Groovy a Kotlin:

  • Podwójne cudzysłowy w przypadku ciągów: Groovy pozwala na definiowanie ciągów za pomocą cudzysłowów pojedynczych, ale 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, użyj nawiasów klamrowych wokół wyrażenia ${project.rootDir}:

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

    Więcej informacji znajdziesz w dokumentacji Kotlina dotyczącej szablonów ciągów znaków.

Zmienianie nazw rozszerzeń plików

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

Najpierw przenieś najmniejsze pliki, aby zdobyć doświadczenie, a potem przejdź do kolejnych. W projekcie możesz mieć mieszankę plików kompilacji Kotlin i Groovy, więc poświęć trochę czasu na ostrożne przeprowadzenie tej zmiany.

Zastąp def tekstem val lub var

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

def building64Bit = false

Oto ten sam kod napisany w języku Kotlin:

val building64Bit = false

Prefiksuj właściwości logiczne prefiksem is

Groovy używa logiki dedukcji właściwości na podstawie nazw właściwości. W przypadku wartości logicznej foo metody wnioskowania mogą być getFoo, setFoo lub isFoo. Dlatego po przekonwertowaniu na Kotlin musisz zmienić nazwy właściwości na metody dedukowane, które nie są obsługiwane przez Kotlin. Na przykład w przypadku elementów logicznych DSL buildTypes musisz użyć prefiksu 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 nazwy właściwości mają przedrostek is.

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

Konwertowanie list i map

Listy i mapy w Groovym i Kotlinie są definiowane za pomocą innej składni. Groovy używa [], a Kotlin wywołuje metody tworzenia kolekcji jawnie, używając listOf lub mapOf. Podczas migracji zastąp [] wartością listOf lub mapOf.

Oto jak zdefiniować listę w Groovy i Kotlinie:

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

Oto ten sam kod napisany w języku Kotlin:

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

Oto jak zdefiniować mapę w Groovym i Kotlinie:

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

Oto ten sam kod napisany 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. Wszystkie inne typy niestandardowych wersji muszą być tworzone 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 działa dobrze w połączeniu 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 w plikach DSL w Kotlinie, ponieważ umożliwia Studio IDE wykonywanie uzupeł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 należą do 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 Kotlina można odwoływać się za pomocą wielu identyfikatorów wtyczek. Zalecamy używanie skrótu identyfikatora w ramach nazwy zasobów i przekształcenie skrótu w identyfikator w ramach nazwy zasobów za pomocą tej tabeli:

Identyfikatory wtyczki Shorthand Identyfikatory w ramach 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 Maven oraz repozytorium Google Maven. Aby dowiedzieć się więcej o tym, jak działają identyfikatory wtyczek, przeczytaj artykuł Tworzenie niestandardowych wtyczek Gradle.

Przeprowadź refaktoryzację

Gdy znasz identyfikatory 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 najwyższego poziomu build.gradle.kts.

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

  5. Usuń wywołanie apply plugin dla wtyczki z 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")

Oto odpowiednia konfiguracja za pomocą 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 przypadku Groovy i Kotlina. Poniższy kod pokazuje, jak stosować w Groovy wtyczki, 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
   ...
}

Ten kod pokazuje, jak zrobić to samo w języku 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)
   ...
}

Poniższy 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'
   ...
}

Ten kod pokazuje, jak zrobić to samo w języku 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 dokumentacji Gradle Zastosowanie wtyczek.

Różne

Przykłady kodu Kotlina do 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 dotyczące podawania informacji, których potrzebujemy do wstępnej oceny problemu, znajdziesz w artykule Szczegóły dotyczące 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

Przykładowy działający plik Gradle napisany w Kotlinie znajdziesz na GitHubie w aplikacji Now In Android.