Migracja konfiguracji kompilacji z Groovy do Kotlin

Wtyczka Androida do obsługi Gradle w wersji 4.0 wprowadziła obsługę języka Kotlin w konfiguracji kompilacji Gradle jako zamiennika języka programowania Groovy, który był tradycyjnie używany w plikach konfiguracyjnych Gradle.

Kotlin jest preferowany od Groovy do pisania skryptów Gradle, ponieważ jest bardziej czytelny i zapewnia lepsze sprawdzanie w czasie kompilacji oraz obsługę IDE.

Kotlin jest obecnie lepiej zintegrowany z edytorem 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 migracji warto wziąć pod uwagę wydajność kompilacji.

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

Oś czasu

Od wersji Android Studio Giraffe nowe projekty domyślnie korzystają z Kotlin DSL (build.gradle.kts) do konfiguracji kompilacji. Zapewnia to lepsze środowisko edycji niż Groovy DSL (build.gradle) dzięki wyróżnianiu składni, uzupełnianiu kodu i nawigacji 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 w języku Kotlin lub czasami do bazowego języka Gradle Kotlin DSL.

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

Nazewnictwo plików skryptów

Nazwy rozszerzeń plików skryptów zależą od języka, w którym napisany jest plik kompilacji:

  • Pliki kompilacji Gradle napisane w Groovy mają rozszerzenie .gradle.
  • Pliki kompilacji Gradle napisane w języku Kotlin mają rozszerzenie .gradle.kts.

Konwertowanie składni

Między Groovy a Kotlinem występują pewne ogólne różnice w składni, dlatego musisz wprowadzić te zmiany w całych skryptach kompilacji.

Dodawanie nawiasów do wywołań metod

Groovy pozwala pominąć nawiasy w wywołaniach metod, a 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 napisany w języku Kotlin:

compileSdkVersion(30)

Dodawanie symbolu = do połączeń dotyczących projektów

W przypadku przypisywania właściwości język Groovy DSL umożliwia pominięcie operatora przypisania =, natomiast Kotlin wymaga jego użycia. Ten kod pokazuje, jak przypisywać 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 języku Kotlin:

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

Konwertowanie ciągów

Oto różnice w ciągach znaków między Groovy a Kotlinem:

  • Cudzysłów podwójny w przypadku ciągów znaków: Groovy umożliwia definiowanie ciągów znaków za pomocą cudzysłowu pojedynczego, ale Kotlin wymaga cudzysłowu podwójnego.

  • Interpolacja ciągów znaków w wyrażeniach z kropkami: w Groovy możesz używać tylko prefiksu $ do interpolacji ciągów znaków w wyrażeniach z kropkami, ale Kotlin wymaga, aby wyrażenia z kropkami były ujęte w nawiasy klamrowe. W Groovy możesz na przykład użyć $project.rootDir, jak pokazano w tym fragmencie kodu:

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

    W Kotlinie powyższy kod wywołuje jednak toString() na 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 sekcji String templates (Szablony ciągów) w dokumentacji języka Kotlin.

Zmienianie rozszerzeń plików

Podczas przenoszenia zawartości każdego pliku kompilacji dodaj do niego znak .kts. Na przykład wybierz plik kompilacji, taki jak plik settings.gradle. Zmień nazwę pliku na settings.gradle.kts i przekonwertuj jego zawartość na język Kotlin. Po migracji każdego pliku kompilacji sprawdź, czy projekt nadal się kompiluje.

Najpierw przenieś najmniejsze pliki, zdobądź doświadczenie, a potem przejdź dalej. W projekcie możesz mieć pliki kompilacji w Kotlinie i Groovym, więc poświęć trochę czasu na dokładne przeprowadzenie migracji.

Zastąp def tekstem val lub var

Zastąp def symbolem val lub var, czyli sposobem definiowania zmiennych w Kotlinie. Oto deklaracja zmiennej w Groovy:

def building64Bit = false

Ten sam kod napisany w języku Kotlin:

val building64Bit = false

Właściwości logiczne poprzedź prefiksem is

Groovy używa logiki wnioskowania o właściwościach na podstawie nazw właściwości. W przypadku właściwości logicznej foo jej wywnioskowane metody mogą mieć postać getFoo, setFoo lub isFoo. Dlatego po przekonwertowaniu na język Kotlin musisz zmienić nazwy właściwości na wywnioskowane metody, które nie są obsługiwane przez ten język. Na przykład w przypadku elementów logicznych DSL buildTypes musisz dodać przedrostek is. Ten kod pokazuje, jak ustawić właściwości logiczne w Groovy:

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

Poniżej znajdziesz ten sam kod w języku Kotlin. Pamiętaj, że właściwości mają prefiks is.

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

Konwertowanie list i map

Listy i mapy w językach Groovy i Kotlin są definiowane za pomocą innej składni. Groovy używa [], a Kotlin wywołuje metody tworzenia kolekcji w sposób jawny, 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>"]

Ten sam kod napisany w języku Kotlin:

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

Oto jak zdefiniować mapę w Groovy i Kotlinie:

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

Ten sam kod napisany w języku Kotlin:

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

Konfigurowanie typów kompilacji

W języku Kotlin DSL dostępne są tylko typy kompilacji debug i kompilacja do publikacji. Wszystkie inne niestandardowe typy kompilacji należy tworzyć ręcznie.

W Groovy możesz używać typów kompilacji debug, release i innych bez ich wcześniejszego tworzenia. Poniższy fragment kodu pokazuje konfigurację z typami kompilacji debug, releasebenchmark w Groovy.

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

Aby utworzyć odpowiednią konfigurację w języku Kotlin, musisz jawnie utworzyć rodzaj kompilacji benchmark.

buildTypes {
 debug {
   ...
 }

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

Migracja z buildscript do bloku wtyczek

Jeśli do dodawania wtyczek do projektu używasz bloku buildscript {}, zmień go na blok plugins {}. Blok plugins {} ułatwia stosowanie wtyczek i dobrze współpracuje z katalogami wersji.

Dodatkowo, gdy w plikach kompilacji używasz bloku plugins {}, Android Studio zna kontekst nawet wtedy, gdy kompilacja się nie powiedzie. Ten kontekst pomaga wprowadzać poprawki w plikach Kotlin DSL, ponieważ umożliwia środowisku IDE Studio uzupełnianie kodu i wyświetlanie innych przydatnych sugestii.

Znajdowanie identyfikatorów wtyczek

Blok buildscript {} dodaje wtyczki do ścieżki klas kompilacji za pomocą współrzędnych Mavena wtyczki, np. com.android.tools.build:gradle:7.4.0, a blok plugins {} używa identyfikatorów wtyczek.

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

Wtyczki Kotlin mogą być przywoływane przez wiele identyfikatorów wtyczek. Zalecamy używanie identyfikatora wtyczki z przestrzenią nazw i przeprowadzenie refaktoryzacji z identyfikatora skróconego na identyfikator wtyczki z przestrzenią nazw zgodnie z tą tabelą:

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

Wtyczek możesz też szukać w portalu wtyczek Gradle, centralnym repozytorium Mavenrepozytorium Maven Google. Więcej informacji o działaniu identyfikatorów wtyczek znajdziesz w artykule Developing Custom Gradle Plugins (Tworzenie niestandardowych wtyczek Gradle).

Przeprowadź refaktoryzację

Gdy poznasz 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. 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. W tym miejscu musisz podać tylko identyfikator wtyczki, ponieważ wersja jest dziedziczona z projektu głównego.

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

Oto równoważna konfiguracja z użyciem 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 języków Groovy i Kotlin. Poniższy kod pokazuje, jak zastosować 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 to samo zrobić w Kotlinie:

// 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 zastosować 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 to samo zrobić w Kotlinie:

// 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 sekcji Stosowanie wtyczek w dokumentacji Gradle.

Pozostałe postanowienia

Przykłady kodu w języku Kotlin dotyczące innych funkcji znajdziesz na tych stronach dokumentacji:

Znane problemy

Znany problem polega na tym, że szybkość kompilacji może być mniejsza w przypadku języka Kotlin niż w przypadku języka Groovy.

Jak zgłaszać problemy

Instrukcje dotyczące podawania informacji potrzebnych do ustalenia priorytetu problemu znajdziesz w artykule Szczegóły dotyczące błędów narzędzi do kompilacji i Gradle. Następnie zgłoś błąd, korzystając z publicznego narzędzia do rejestrowania problemów Google.

Więcej zasobów

Działający przykład plików kompilacji Gradle napisanych w Kotlinie znajdziesz w przykładowej aplikacji Now In Android w GitHubie.