Interdependencias de herramientas y bibliotecas

Las dependencias de compilación son componentes externos necesarios para compilar correctamente tu proyecto. Una compilación puede depender de bibliotecas, complementos, subproyectos, el SDK de Android, herramientas como los compiladores de Kotlin y Java, entornos de desarrollo como Android Studio y Gradle.

Cada dependencia puede requerir otras dependencias. Estas se denominan dependencias transitivas y pueden aumentar con rapidez las dependencias generales que usa tu aplicación. Cuando quieras actualizar una dependencia, ya sea una biblioteca, una herramienta o el SDK de Android, esa actualización puede realizarse en cascada y actualizar muchas otras dependencias.

A menudo, esto no causará problemas, ya que muchas bibliotecas siguen un esquema conocido como control de versiones semántico. Estas bibliotecas restringen los tipos de cambios que realizan para proporcionar compatibilidad con sus versiones anteriores.

El control de versiones semántico sigue un formato major.minor.patch. Por ejemplo, en el número de versión 4.8.3, 4 es la versión major, 8 es la versión minor y 3 es el número de patch. Cuando cambia la parte major, es posible que la biblioteca tenga cambios rotundos en la API o el comportamiento. Esto puede afectar el comportamiento de tu compilación o aplicación.

Cuando cambian las partes minor (funciones nuevas) o patch (correcciones de errores), los desarrolladores de la biblioteca te indican que la biblioteca sigue siendo compatible y no debería afectar tu aplicación.

Relaciones en tu compilación

Las compilaciones de Android contienen relaciones entre los siguientes elementos:

  • Código fuente: el código y los recursos sobre los que tienes control
  • Dependencias de biblioteca: Son bibliotecas o módulos externos que tu proyecto y sus subproyectos incluyen cuando se compilan.
  • Herramientas: compiladores, complementos y SDKs que traducen tu código fuente en una aplicación o biblioteca
Dependencias de compilación y sus relaciones
Figura 1. Entablar relaciones

Código fuente

Tu código fuente es el código de Kotlin o Java que escribes en tu aplicación o biblioteca. (Para obtener detalles sobre el uso de C++, consulta NDK de Android).

El código fuente depende de las bibliotecas (incluidas las bibliotecas de entorno de ejecución de Kotlin y Java) y del SDK de Android, y requiere su compilador de Kotlin o Java correspondiente.

Algunos códigos fuente incluyen anotaciones que requieren procesamiento adicional. Por ejemplo, si escribes código de Jetpack Compose, agregas anotaciones como @Composable que debe procesar el complemento del compilador de Kotlin para Compose. Otras anotaciones se pueden procesar con un procesador de símbolos de Kotlin (KSP) o con herramientas de procesamiento de anotaciones independientes.

Dependencias de bibliotecas

Las bibliotecas contienen código de bytes que se extrae como parte de tu aplicación. Puede ser un JAR de Java, una biblioteca de Android (AAR) o un subproyecto en tu compilación. Muchas bibliotecas siguen el control de versiones semántico, que puede ayudarte a comprender cuándo siguen siendo compatibles (o no) cuando se actualizan.

Las bibliotecas suelen tener dependencias transitivas de otras bibliotecas. Esto reduce lo que debes administrar de forma explícita: especificas las dependencias directas y Gradle las incorpora junto con las transitivas. Actualizar las dependencias directas también puede actualizar sus dependencias transitivas.

A veces, una biblioteca puede requerir versiones mínimas del SDK de Android en el entorno de ejecución (minSdk) o en el tiempo de compilación (compileSdk). Esto es necesario cuando una biblioteca usa funciones incluidas en el SDK de Android o en las APIs de JDK que proporciona. El minSdk efectivo de tu aplicación es el minSdk más alto que solicita tu aplicación y todas sus dependencias de biblioteca directas y transitivas.

Para usar algunas bibliotecas, es posible que debas usar un complemento de Gradle específico. Estos complementos auxiliares suelen instalar procesadores de símbolos de Kotlin o de otras anotaciones que generan código o modifican la compilación de tu fuente para admitir el uso de las funciones de la biblioteca. Por ejemplo, Jetpack Room incluye anotaciones y un KSP que las transforma en código generado para recuperar y modificar datos en una base de datos. Jetpack Compose requiere el complemento del compilador de Compose para modificar las funciones anotadas y administrar cómo y cuándo se vuelve a ejecutar esa función.

Herramientas

Gradle

Gradle es la herramienta de compilación que lee tus archivos de compilación y genera tu aplicación o biblioteca, y también expone una API para que los complementos extiendan sus capacidades. Gradle ejecuta varios procesos en una o más máquinas virtuales de Java, y sus complementos de Java llaman a las herramientas de Java dentro del JDK.

Complementos de Gradle

Los complementos de Gradle extienden Gradle definiendo tareas y configuraciones nuevas. Aplicar un complemento a tu compilación habilita funciones de compilación específicas, configuradas como datos en tus secuencias de comandos de compilación. Para las compilaciones de Android, el complemento de Gradle más importante es el complemento de Android para Gradle (AGP).

Compiladores

El compilador de Kotlin o Java transforma tu código fuente en código de bytes ejecutable. El compilador de Kotlin expone una API de complemento que permite que el análisis externo y la generación de código se ejecuten directamente dentro del compilador, lo que permite acceder a la estructura de código analizada.

Complementos del compilador

Los complementos del compilador realizan análisis y generación de código dentro del compilador de Kotlin mientras este analiza tu código, y se instalan cuando aplicas sus complementos de Gradle a la compilación.

SDK de Android

El SDK de Android contiene la plataforma de Android y las APIs de Java para una versión específica de Android, además de sus herramientas correspondientes. Estas herramientas te ayudan a administrar el SDK, compilar tus aplicaciones, y comunicarte con dispositivos Android y emularlos.

Cada versión del SDK de Android proporciona APIs de Java específicas a las que puede acceder tu código fuente y compatibilidad con la expansión de sintaxis para usar esas APIs en versiones anteriores de Android.

JDK

El Java Development Kit, que contiene bibliotecas y ejecutables de Java para compilar el código fuente de Java y ejecutar aplicaciones de Java Hay varios JDK en juego en una compilación de Android. Consulta Versiones de Java en compilaciones de Android para obtener más detalles.

Permisos de Gradle

Gradle agrupa las dependencias de bibliotecas en diferentes alcances (llamados configuraciones en la API de Gradle), lo que te permite especificar diferentes conjuntos de dependencias de bibliotecas para usar en diferentes partes de tu compilación. Por ejemplo, es probable que no quieras incluir bibliotecas de pruebas, como JUnit, en tu aplicación o biblioteca publicada, pero sí las necesitas cuando compilas y ejecutas tus pruebas de unidades. También usas los permisos para agregar procesadores de símbolos o anotaciones para analizar tu código.

Por ejemplo, el AGP define los permisos implementation y api, que es tu forma de especificar si una dependencia debe exponerse a los usuarios de tu subproyecto. Consulta Cómo configurar dependencias para obtener descripciones de estos y otros permisos que se usan en una compilación de Android.

Agrega dependencias de biblioteca en el bloque dependencies de tus archivos de compilación, ya sea como cadenas group:artifact:version:

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

Groovy

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

o en un catálogo de versiones:

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

y especifica las variables generadas en tus archivos de compilación:

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

Groovy

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}