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.

Przy pisaniu skryptów Gradle preferuje Kotlin, ponieważ Kotlin jest bardziej czytelny i zapewnia lepszą obsługę IDE oraz sprawdzanie 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 większy komfort edycji niż Groovy DSL (build.gradle) z podświetlaniem składni, uzupełnianiem kodu i przechodzeniem do deklaracji. Więcej informacji znajdziesz w artykule Gradle Kotlin DSL Primer.

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 legendarnego interfejsu Gradle Kotlin DSL.

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

Nazewnictwo plików skryptu

Nazwy rozszerzeń plików skryptów zależą od języka, w którym zapisano 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)

Dodaj użytkownika = do połączeń w ramach przypisania

Groovy DSL pozwala pominąć operator przypisania = podczas przypisywania właściwości, a 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 przypisać właściwości w Kotlin:

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

Konwertuj ciągi znaków

Groovy i Kotlin mają te różnice:

  • 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ągów znaków w wyrażeniach z kropkami: w Groovy możesz używać tylko prefiksu $ dla interpolacji ciągów znaków w wyrażeniach z kropkowaną kropką, ale Kotlin wymaga umieszczania kropkowanych wyrażeń w nawiasach klamrowych. Na przykład w Groovy możesz użyć elementu $project.rootDir w sposób pokazany w tym fragmencie:

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

    Jednak w Kotlin poprzedni kod wywołuje toString() na stronie project, a nie na 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

Dołącz .kts do każdego pliku kompilacji podczas przenoszenia jego zawartości. Na przykład wybierz plik kompilacji taki jak settings.gradle. Zmień nazwę pliku na settings.gradle.kts, a jego zawartość przekonwertuj na Kotlin. Upewnij się, że po migracji każdego pliku kompilacji projekt nadal się skompiluje.

Zacznij od migracji najmniejszych plików, zyskaj doświadczenie i dopiero potem kontynuuj. W projekcie możesz używać zarówno plików kompilacji Kotlin, jak i Groovy, więc uważnie wykonaj swoje działania.

Zamień def na val lub var

Zastąp def kodem val lub var, czyli sposobem definiowania zmiennych w Kotlin. To jest deklaracja zmiennej w Groovy:

def building64Bit = false

Ten sam kod jest zapisany w kotlinie:

val building64Bit = false

Właściwości logiczne prefiksu z is

Groovy korzysta z logiki odliczenia 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 buildTypes DSL musisz poprzedzić je prefiksem is. Ten kod pokazuje, jak ustawić w Groovy właściwości logiczne:

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

Poniżej znajduje się ten sam kod w 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
            ...
        }
    ...

Konwertuj listy i mapy

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.

Aby zdefiniować listę w trybie Groovy i Kotlin:

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

Ten sam kod jest zapisany w kotlinie:

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

Oto jak zdefiniować mapę w grze Groovy vs Kotlin:

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

Ten sam kod jest zapisany w kotlinie:

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

Skonfiguruj typy kompilacji

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

W Groovy możesz korzystać z debugowania, wersji i innych typów kompilacji bez ich wcześniejszego tworzenia. Ten fragment kodu przedstawia konfigurację z typami kompilacji debug, release i benchmark w Groovy.

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

Aby utworzyć równoważną konfigurację w Kotlin, musisz bezpośrednio utworzyć typ kompilacji benchmark.

buildTypes {
 debug {
   ...
 }

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

Przejście z kompilacji na blok wtyczek

Jeśli w kompilacji do dodawania wtyczek do projektu jest używany blok buildscript {}, musisz zastosować refaktoryzację, aby zamiast tego użyć bloku plugins {}. Blok plugins {} ułatwia stosowanie wtyczek i dobrze działa z katalogami wersji.

Ponadto jeśli w plikach kompilacji używasz bloku plugins {}, Android Studio zna kontekst nawet w przypadku niepowodzenia kompilacji. Ten kontekst pomaga w naprawianiu plików DSL Kotlin, ponieważ umożliwia IDE Studio wykonywanie kodu i dostarczanie innych przydatnych sugestii.

Znajdowanie identyfikatorów wtyczek

Blok buildscript {} dodaje wtyczki do ścieżki klasy kompilacji za pomocą współrzędnych Maven wtyczki, np. com.android.tools.build:gradle:7.4.0, ale blok plugins {} korzysta z identyfikatorów wtyczek.

W przypadku większości wtyczek identyfikator to ciąg znaków używany podczas ich stosowania za pomocą 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:

Skrócone identyfikatory wtyczek 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 Maven i repozytorium Google Maven. Przeczytaj artykuł Opracowywanie niestandardowych wtyczek Gradle, aby dowiedzieć się więcej o działaniu identyfikatorów wtyczek.

Przeprowadź refaktoryzację.

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

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

  2. Dodaj wtyczki do bloku plugins {} w pliku build.gradle najwyższego poziomu. Musisz tutaj podać identyfikator i wersję wtyczki. Jeśli nie trzeba stosować wtyczki 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 wtyczki apply plugin z pliku build.gradle na poziomie modułu.

Na przykład ta konfiguracja używa 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.

Inne

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

Znane problemy

Obecnie znanym problemem jest to, że w kotlinie szybkość kompilacji może być mniejsza 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 Google do rejestrowania problemów.

Więcej materiałów

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