Cómo migrar tu configuración de compilación de Groovy a Kotlin

El complemento de Android para Gradle 4.0 agregó compatibilidad con el uso de Kotlin en la configuración de compilación de Gradle como reemplazo de Groovy, el lenguaje de programación que se usa tradicionalmente en los archivos de configuración de Gradle.

Se prefiere Kotlin en lugar de Groovy para escribir secuencias de comandos de Gradle, ya que Kotlin es más legible y ofrece una mejor revisión de tiempo de compilación y compatibilidad con IDE.

Si bien actualmente Kotlin ofrece una mejor integración en el editor de código de Android Studio en comparación con Groovy, las compilaciones que usan Kotlin suelen ser más lentas que las que usan Groovy, por lo que debe tenerse en cuenta el rendimiento al momento de migrar.

En esta página, se proporciona información básica sobre la conversión de los archivos de compilación de Gradle de tu app para Android de Groovy a Kotlin. Para obtener una guía de migración más completa, consulta la documentación oficial de Gradle.

Cronograma

A partir de Android Studio Giraffe, los proyectos nuevos usan la DSL de Kotlin (build.gradle.kts) de forma predeterminada para la configuración de compilación. Esto ofrece una mejor experiencia de edición que la DSL de Groovy (build.gradle) con resaltado de sintaxis, finalización de código y navegación a declaraciones. Para obtener más información, consulta el Primer DSL de Kotlin de Gradle.

Términos comunes

DSL de Kotlin: Hace referencia principalmente al DSL de Kotlin del complemento de Android para Gradle o bien, en algunas ocasiones, al DSL de Kotlin de Gradle subyacente.

En esta guía de migración, se usan indistintamente los términos "Kotlin" y "DSL de Kotlin". Del mismo modo, "Groovy" y "DSL de Groovy" se usan indistintamente.

Asignación de nombres de archivos de la secuencia de comandos

Los nombres de las extensiones de archivo de secuencia de comandos se basan en el lenguaje en el que se escribe el archivo de compilación:

  • Los archivos de compilación de Gradle escritos en Groovy usan la extensión de archivo .gradle.
  • Los archivos de compilación de Gradle escritos en Kotlin usan la extensión de archivo .gradle.kts.

Cómo convertir la sintaxis

Existen algunas diferencias generales en la sintaxis entre Groovy y Kotlin, por lo que debes aplicar estos cambios en tus secuencias de comandos de compilación.

Cómo agregar paréntesis a las llamadas de método

Groovy te permite omitir los paréntesis en las llamadas de método, mientras que Kotlin los requiere. Para migrar tu configuración, agrega paréntesis a estos tipos de llamadas de método. En este código, se muestra cómo establecer una configuración en Groovy:

compileSdkVersion 30

Este es el mismo código escrito en Kotlin:

compileSdkVersion(30)

Cómo agregar a = a las llamadas de asignación

El DSL de Groovy te permite omitir el operador de asignación = cuando se asignan propiedades, mientras que Kotlin lo requiere. En este código, se muestra cómo asignar propiedades en Groovy:

java {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

En este código, se muestra cómo asignar propiedades en Kotlin:

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

Cómo convertir cadenas

Estas son las diferencias entre las cadenas de Groovy y Kotlin:

  • Comillas dobles para cadenas: Si bien Groovy permite que las cadenas se definan con comillas simples, Kotlin requiere comillas dobles.
  • Interpolación de cadenas en expresiones punteadas: En Groovy, puedes usar solo el prefijo $ para las interpolaciones de cadenas en expresiones punteadas, pero Kotlin requiere que unas las expresiones punteadas con llaves. Por ejemplo, en Groovy, puedes usar $project.rootDir como se muestra en el siguiente fragmento:

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

    Sin embargo, en Kotlin, el código anterior llama a toString() en project, no en project.rootDir. Para obtener el valor del directorio raíz, une la expresión ${project.rootDir} con llaves:

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

    Para obtener más información, consulta Plantillas de strings en la documentación de Kotlin.

Cómo cambiar el nombre de las extensiones de archivo

Agrega .kts a cada archivo de compilación a medida que migras su contenido. Por ejemplo, selecciona un archivo de compilación, como el archivo settings.gradle. Cambia el nombre del archivo por settings.gradle.kts y convierte el contenido del archivo en Kotlin. Asegúrate de que tu proyecto se compile de todas formas después de una migración de cada archivo de compilación.

Primero, migra tus archivos más pequeños, obtén experiencia y luego continúa. Puedes tener una combinación de archivos de compilación de Kotlin y Groovy en un proyecto, por lo que debes tomarte el tiempo necesario para realizar el cambio con cuidado.

Reemplaza def por val o var.

Reemplaza def por val o var, que es cómo defines variables en Kotlin. Esta es una declaración de variable en Groovy:

def building64Bit = false

Este es el mismo código escrito en Kotlin:

val building64Bit = false

Agrega el prefijo is a las propiedades booleanas

Groovy usa lógica de deducción de propiedades basada en los nombres de las propiedades. Los métodos deducidos de una propiedad booleana foo pueden ser getFoo, setFoo o isFoo. Por lo tanto, una vez que los conviertes a Kotlin, debes cambiar los nombres de las propiedades por los métodos deducidos que no son compatibles con Kotlin. Por ejemplo, debes anteponer el prefijo is a los elementos booleanos buildTypes de DSL. En este código, se muestra cómo establecer propiedades booleanas en Groovy:

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

El siguiente código es el mismo en Kotlin. Ten en cuenta que las propiedades tienen el prefijo is.

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

Cómo convertir listas y mapas

Las listas y los mapas de Groovy y Kotlin se definen con una sintaxis diferente. Groovy usa [], mientras que Kotlin llama a métodos de creación de colecciones de manera explícita con listOf o mapOf. Asegúrate de reemplazar [] por listOf o mapOf cuando realices la migración.

A continuación, te mostramos cómo definir una lista en Groovy en comparación con Kotlin:

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

Este es el mismo código escrito en Kotlin:

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

A continuación, te mostramos cómo definir un mapa en Groovy y en Kotlin:

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

Este es el mismo código escrito en Kotlin:

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

Cómo configurar tipos de compilaciones

En el DSL de Kotlin, solo los tipos de compilación de depuración y lanzamiento están disponibles de forma implícita. Todos los demás tipos de compilación personalizados deben crearse manualmente.

En Groovy, puedes usar la depuración, la versión y ciertos otros tipos de compilación sin crearlos primero. En el siguiente fragmento de código, se muestra una configuración con los tipos de compilación debug, release y benchmark en Groovy.

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

Para crear la configuración equivalente en Kotlin, debes crear de forma explícita el tipo de compilación benchmark.

buildTypes {
 debug {
   ...
 }

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

Cómo migrar de buildscript al bloque de complementos

Si tu compilación usa el bloque buildscript {} para agregar complementos al proyecto, debes refactorizar para usar el bloque plugins {}. El bloque plugins {} facilita la aplicación de complementos y funciona bien con los catálogos de versiones.

Además, cuando usas el bloqueo de plugins {} en tus archivos de compilación, Android Studio está al tanto del contexto incluso cuando la compilación falla. Este contexto ayuda a corregir tus archivos de DSL de Kotlin, ya que permite que el IDE de Studio complete el código y brinde otras sugerencias útiles.

Cómo encontrar los IDs de los complementos

Mientras que el bloque buildscript {} agrega los complementos a la ruta de acceso de compilación con las coordenadas de Maven del complemento, por ejemplo, com.android.tools.build:gradle:7.4.0, el bloque plugins {} usa los IDs de complemento en su lugar.

Para la mayoría de los complementos, el ID del complemento es la cadena que se usa cuando los aplicas con apply plugin. Por ejemplo, los siguientes IDs de complementos forman parte del complemento de Android para Gradle:

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

Puedes encontrar la lista completa de complementos en el repositorio de Google Maven.

Se puede hacer referencia a los complementos de Kotlin con varios IDs de complementos. Te recomendamos que uses el ID del complemento con espacio de nombres y refactorices del ID de complemento abreviado al ID de complemento con espacio de nombres según la siguiente tabla:

IDs de complementos abreviados IDs de complementos con espacio de nombres
kotlin org.jetbrains.kotlin.jvm
kotlin-android org.jetbrains.kotlin.android
kotlin-kapt org.jetbrains.kotlin.kapt
kotlin-parcelize org.jetbrains.kotlin.plugin.parcelize

También puedes buscar complementos en el portal de complementos de Gradle, el repositorio central de Maven y el repositorio de Google Maven. Lee Developing Custom Gradle Plugins para obtener más información sobre cómo funcionan los IDs de complementos.

Realiza la refactorización

Una vez que conozcas los IDs de los complementos que usas, sigue estos pasos:

  1. Si aún tienes repositorios para complementos declarados en el bloque buildscript {}, muévelos al archivo settings.gradle.

  2. Agrega los complementos al bloque plugins {} en el archivo build.gradle de nivel superior. Debes especificar el ID y la versión del complemento aquí. Si no es necesario que el complemento se aplique al proyecto raíz, usa apply false.

  3. Quita las entradas classpath del archivo build.gradle.kts de nivel superior.

  4. Para aplicar los complementos, agrégalos al bloque plugins {} en el archivo build.gradle a nivel del módulo. Solo debes especificar el ID del plugin aquí porque la versión se hereda del proyecto raíz.

  5. Quita la llamada apply plugin del complemento del archivo build.gradle de nivel de módulo.

Por ejemplo, esta configuración usa el bloque 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")

Esta es una configuración equivalente que usa el bloque 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()
    }
}

Cómo convertir el bloque de complementos

Aplicar complementos desde el bloque plugins {} es similar en Groovy y Kotlin. En el siguiente código, se muestra cómo aplicar complementos en Groovy cuando usas catálogos de versiones:

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

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

En el siguiente código, se muestra cómo hacer lo mismo en 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)
   ...
}

En el siguiente código, se muestra cómo aplicar complementos en Groovy cuando no usas catálogos de versiones:

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

En el siguiente código, se muestra cómo hacer lo mismo en 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")
   ...
}

Para obtener más detalles sobre el bloque plugins {}, consulta la documentación de Gradle sobre cómo aplicar complementos.

Varios

Si deseas ver muestras de código de Kotlin para otras funciones, consulta las siguientes páginas de la documentación:

Problemas conocidos

En la actualidad, un problema conocido es que la velocidad de compilación puede ser más lenta con Kotlin que con Groovy.

Cómo denunciar los problemas

Si deseas obtener instrucciones sobre cómo brindar la información que necesitamos para clasificar tu problema, consulta Detalles de errores de Gradle y de herramientas de compilación. Luego, informa un error con la Herramienta pública de seguimiento de errores de Google.

Más recursos

Para ver un ejemplo en funcionamiento de archivos de compilación de Gradle escritos con Kotlin, consulta la app de ejemplo Now In Android en GitHub.