Cómo agregar dependencias de compilación

El sistema de compilación de Gradle en Android Studio facilita la inclusión de objetos binarios externos o de otros módulos de biblioteca a tu compilación como dependencias. Las dependencias pueden ubicarse en tu máquina o en un repositorio remoto, y cualquier dependencia transitiva que estas declaren se incluirá automáticamente. En esta página, se describe el modo de uso de las dependencias con tu proyecto de Android, incluidos los detalles sobre los comportamientos y las opciones de configuración que son específicos del complemento de Android para Gradle. A fin de obtener una guía conceptual más detallada sobre las dependencias de Gradle, también deberías consultar la Guía de Gradle para la administración de dependencias. Sin embargo, recuerda que tu proyecto de Android solo debe usar los parámetros de configuración de dependencias que se definen en esta página.

Tipos de dependencias

Para agregar una dependencia a tu proyecto, especifica una configuración de dependencias, como implementation, en el bloque dependencies de tu archivo build.gradle.

En el siguiente archivo build.gradle, por ejemplo, para un módulo de app se incluyen tres tipos diferentes de dependencias:

Groovy

plugins {
  id 'com.android.application'
}

android { ... }

dependencies {
    // Dependency on a local library module
    implementation project(':mylibrary')

    // Dependency on local binaries
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
}

Kotlin

plugins {
    id("com.android.application")
}

android { ... }

dependencies {
    // Dependency on a local library module
    implementation(project(":mylibrary"))

    // Dependency on local binaries
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))

    // Dependency on a remote binary
    implementation("com.example.android:app-magic:12.3")
}

Cada una de ellas requiere una clase diferente de dependencias de bibliotecas:

Dependencia del módulo de biblioteca local

Groovy

implementation project(':mylibrary')

Kotlin

implementation(project(":mylibrary"))

De esta manera, se declara una dependencia en un módulo de biblioteca de Android llamado "mylibrary" (ese nombre debe coincidir con el nombre de biblioteca definido con include: en tu archivo settings.gradle). Cuando compilas tu app, el sistema de compilación crea el módulo de biblioteca y empaqueta el contenido compilado resultante en la app.

Dependencia binaria local

Groovy

  implementation fileTree(dir: 'libs', include: ['*.jar'])
  

Kotlin

  implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
  

Gradle declara las dependencias de los archivos JAR dentro del directorio module_name/libs/ de tu proyecto (porque lee rutas relacionadas con el archivo build.gradle).

Como alternativa, puedes especificar archivos individuales de la siguiente manera:

Groovy

  implementation files('libs/foo.jar', 'libs/bar.jar')
  

Kotlin

  implementation(files("libs/foo.jar", "libs/bar.jar"))
  
Dependencia binaria remota

Groovy

  implementation 'com.example.android:app-magic:12.3'
  

Kotlin

  implementation("com.example.android:app-magic:12.3")
  

En realidad, esta es una versión abreviada de lo siguiente:

Groovy

  implementation group: 'com.example.android', name: 'app-magic', version: '12.3'

Kotlin

  implementation(group = "com.example.android", name = "app-magic", version = "12.3")

De esta manera, se declara una dependencia en la versión 12.3 de la biblioteca "app-magic", dentro del grupo de espacios de nombres "com.example.android".

Nota: Las dependencias remotas como esta requieren que declares los repositorios remotos adecuados en los que Gradle debería buscar la biblioteca. Si la biblioteca no existe localmente, Gradle la obtendrá del sitio remoto cuando la compilación la requiera (por ejemplo, cuando haces clic en Sync Project with Gradle Files  o ejecutas una compilación).

Dependencias nativas

A partir del complemento de Android para Gradle 4.0, las dependencias nativas también se pueden importar de la manera que se describe en este documento.

Según el archivo AAR que exponga bibliotecas nativas, estarán disponibles automáticamente para el sistema de compilación que usa el elemento externalNativeBuild. Para acceder a las bibliotecas desde el código, debes vincularlas con las secuencias de comandos de la compilación nativa. Consulta Cómo usar dependencias nativas en este documento.

Configuraciones de dependencias

Dentro del bloque dependencies, puedes declarar una dependencia de biblioteca usando una de las diferentes configuraciones de dependencias (como implementation, que se muestra arriba). La configuración de cada dependencia le proporciona a Gradle diferentes instrucciones sobre cómo usarla. En la siguiente tabla, se describe cada una de las configuraciones que puedes usar para una dependencia en tu proyecto de Android. Además, se comparan estas opciones de configuración con las que dejaron de estar disponibles a partir de la versión 3.0.0 del complemento de Android para Gradle.

Configuración Comportamiento
implementation Gradle agrega la dependencia a la ruta de clase de la compilación y la empaqueta en el resultado de la compilación. Sin embargo, cuando tu módulo configura una dependencia implementation, se le informa a Gradle que no quieres que el módulo filtre la dependencia a otros módulos en el momento de la compilación. Es decir, la dependencia estará disponible para otros módulos solo durante el tiempo de ejecución.

El uso de esta configuración de dependencia, en lugar de api o compile (no disponible), puede reducir en gran medida el tiempo de compilación, ya que disminuye la cantidad de módulos que el sistema debe volver a compilar. Por ejemplo, si una dependencia implementation cambia su API, Gradle solo volverá a compilar esa dependencia y los módulos que dependen de esta directamente. La mayoría de los módulos de prueba y de apps deben usar esta configuración.

api Gradle agrega la dependencia a la ruta de clase y al resultado de la compilación. Cuando un módulo incluye una dependencia api, se le indica a Gradle que el módulo quiere exportar de forma transitiva esa dependencia a otros módulos, de manera que esté disponible para ellos tanto en el tiempo de ejecución como en el de compilación.

Esta configuración tiene el mismo comportamiento que compile (que dejó de estar disponible), pero deberías usarla con cuidado y únicamente con las dependencias que necesitas exportar de forma transitiva a otros consumidores ascendentes, ya que si una dependencia api cambia su API externa, Gradle volverá a compilar todos los módulos que tengan acceso a esa dependencia en el tiempo de compilación. Por lo tanto, tener una gran cantidad de dependencias api puede aumentar en gran medida el tiempo de compilación. A menos que quieras exponer una API de dependencia en un módulo separado, los módulos de biblioteca deberían usar dependencias implementation.

compileOnly Gradle solo agrega la dependencia a la ruta de clase de la compilación (pero no al resultado de la compilación), lo que resulta útil cuando creas un módulo de Android y necesitas la dependencia durante la compilación. Sin embargo, tenerla presente durante el tiempo de ejecución es opcional.

Si usas esta configuración, entonces tu módulo de biblioteca debe incluir una condición de tiempo de ejecución para comprobar si la dependencia está disponible y, luego, cambiar de manera fluida su comportamiento a fin de que pueda funcionar en caso de que esta no se proporcione. De este modo, se reduce el tamaño de la app final, ya que no se agregan dependencias transitivas que no sean fundamentales. Esta configuración tiene el mismo comportamiento que provided (que dejó de estar disponible).

Nota: No puedes usar la configuración compileOnly con dependencias de AAR.

runtimeOnly Gradle solo agrega la dependencia al resultado de la compilación para usar durante el tiempo de ejecución. Es decir, esta no se agrega a la ruta de clase de compilación. Esta configuración tiene el mismo comportamiento que apk (que dejó de estar disponible).
annotationProcessor

Si quieres agregar una dependencia en una biblioteca que es un procesador de anotaciones, debes hacerlo en la ruta de clase del procesador de anotaciones mediante la configuración annotationProcessor, ya que de esta manera se mejora el rendimiento de la compilación porque se separa la ruta de clase de la compilación de la del procesador de anotaciones. Si Gradle encuentra procesadores de anotaciones en la ruta de clase de la compilación, desactivará la elusión de compilación, lo que afectará negativamente el tiempo de compilación (a partir de la versión 5.0 de Gradle, se ignoran los procesadores de anotaciones que se encuentran en la ruta de clase de la compilación).

El complemento de Android para Gradle entiende que una dependencia es un procesador de anotaciones si su archivo JAR contiene el siguiente archivo:

META-INF/services/javax.annotation.processing.Processor

Si el complemento detecta un procesador de anotaciones que está en la ruta de clase de la compilación, se producirá un error de compilación.

Nota: Los proyectos de Kotlin deben usar kapt para declarar dependencias del procesador de anotaciones.

lintChecks

Usa esta configuración para incluir comprobaciones de lint que quieras que Gradle ejecute cuando compiles tu proyecto.

Nota: Si usas la versión 3.4.0 del complemento de Android para Gradle o una versión posterior, esta configuración de dependencia ya no empaqueta las comprobaciones de Lint en tus proyectos de la biblioteca de Android. Para incluir dependencias de comprobaciones de Lint en tus bibliotecas AAR, usa la configuración lintPublish que se describe a continuación.

lintPublish Utiliza esta configuración en los proyectos de la biblioteca de Android para incluir comprobaciones de Lint que quieras que Gradle compile en un archivo lint.jar y empaquete en tu AAR. De esa forma, los proyectos que consumen tu AAR también aplican esas comprobaciones de Lint. Si anteriormente usabas la configuración de dependencia lintChecks para incluir comprobaciones de lint en el AAR publicado, deberás migrar esas dependencias a fin de usar la configuración lintPublish.

Groovy


dependencies {
  // Executes lint checks from the ':checks' project at build time.
  lintChecks project(':checks')
  // Compiles lint checks from the ':checks-to-publish' into a
  // lint.jar file and publishes it to your Android library.
  lintPublish project(':checks-to-publish')
}

Kotlin


dependencies {
  // Executes lint checks from the ":checks" project at build time.
  lintChecks(project(":checks"))
  // Compiles lint checks from the ":checks-to-publish" into a
  // lint.jar file and publishes it to your Android library.
  lintPublish(project(":checks-to-publish"))
}

Opciones de configuración obsoletas de Gradle (disponibles en AGP 1.0-4.2)

Configuración Comportamiento
apk Gradle solo agrega la dependencia al resultado de la compilación para usar durante el tiempo de ejecución. Es decir, esta no se agrega a la ruta de clase de compilación.
compile Gradle agrega la dependencia a la ruta de clase y al resultado de la compilación. Exporta la dependencia a otros módulos.
provided Gradle solo agrega la dependencia a la ruta de clase de la compilación (pero no al resultado).

Todas las configuraciones que se muestran más arriba aplican dependencias a todas las variantes de compilación. Sin embargo, si quieres declarar una dependencia para un solo conjunto de orígenes de variantes de compilación específico o un conjunto de orígenes de prueba, deberás escribir con mayúscula el nombre de la configuración y agregarle el nombre del conjunto de orígenes de prueba o de variantes de compilación como prefijo.

Por ejemplo, si quieres agregar una dependencia implementation a tu variante de producto "gratuito" únicamente (por medio de una dependencia binaria remota), tendrá el siguiente aspecto:

Groovy

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:9.8.0'
}

Kotlin

dependencies {
    freeImplementation("com.google.firebase:firebase-ads:9.8.0")
}

Sin embargo, si deseas agregar una dependencia para una variante que combina una variante de producto con un tipo de compilación, deberás inicializar el nombre de la configuración en el bloque configurations. En el siguiente ejemplo, se agrega una dependencia runtimeOnly a tu variante de compilación "freeDebug" (mediante una dependencia binaria local):

Groovy

configurations {
    // Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration.
    freeDebugRuntimeOnly {}
}

dependencies {
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
}

Kotlin

// Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration.
val freeDebugRuntimeOnly by configurations.creating

dependencies {
    freeDebugRuntimeOnly(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Las dependencias implementation que agregues en las pruebas instrumentadas y las locales tendrán el siguiente aspecto:

Groovy

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.0.2'
}

Kotlin

dependencies {
    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("androidx.test.espresso:espresso-core:3.0.2")
}

Sin embargo, algunas opciones de configuración no son útiles en esta situación. Por ejemplo, como otros módulos no pueden depender de androidTest, verás la siguiente advertencia si usas la configuración androidTestApi:

WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
'androidTestImplementation'.

Cómo agregar procesadores de anotaciones

Si agregas procesadores de anotaciones a la ruta de clase de tu compilación, verás un mensaje de error similar al siguiente:

Error: Annotation processors must be explicitly declared now.

Para corregir este error, agrega procesadores de anotaciones a tu proyecto mediante la configuración de tu dependencia con annotationProcessor, como se muestra a continuación:

Groovy

dependencies {
    // Adds libraries defining annotations to only the compile classpath.
    compileOnly 'com.google.dagger:dagger:version-number'
    // Adds the annotation processor dependency to the annotation processor classpath.
    annotationProcessor 'com.google.dagger:dagger-compiler:version-number'
}

Kotlin

dependencies {
    // Adds libraries defining annotations to only the compile classpath.
    compileOnly("com.google.dagger:dagger:version-number")
    // Adds the annotation processor dependency to the annotation processor classpath.
    annotationProcessor("com.google.dagger:dagger-compiler:version-number")
}

Nota: El complemento de Android para Gradle 3.0.0+ ya no admite el complemento android-apt.

Cómo pasar argumentos a procesadores de anotaciones

Si necesitas pasar argumentos a un procesador de anotaciones, puedes hacerlo mediante el bloque AnnotationProcessorOptions en la configuración de compilación de tu módulo. Por ejemplo, si quieres transmitir tipos de datos primitivos como pares clave-valor, puede utilizar la propiedad argument, como se muestra a continuación:

Groovy

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                argument 'key1', 'value1'
                argument 'key2', 'value2'
            }
        }
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments += mapOf("key1" to "value1",
                                   "key2" to "value2")
            }
        }
    }
}

Sin embargo, cuando uses el complemento de Android para Gradle 3.2.0 o versiones posteriores, necesitarás pasar argumentos de procesadores que representen archivos o directorios por medio de la interfaz CommandLineArgumentProvider de Gradle.

Usar CommandLineArgumentProvider te permite a ti o al autor del procesador de anotaciones mejorar la precisión y el rendimiento de las compilaciones incrementales y las que borraron su caché aplicando anotaciones del tipo de propiedad de compilación incremental a cada argumento.

Por ejemplo, la clase que se muestra a continuación implementa CommandLineArgumentProvider y anota cada argumento para el procesador. En este ejemplo, también se usa la sintaxis del lenguaje Groovy y se incluye directamente en el archivo build.gradle del módulo.

Groovy

class MyArgsProvider implements CommandLineArgumentProvider {

    // Annotates each directory as either an input or output for the
    // annotation processor.
    @InputFiles
    // Using this annotation helps Gradle determine which part of the file path
    // should be considered during up-to-date checks.
    @PathSensitive(PathSensitivity.RELATIVE)
    FileCollection inputDir

    @OutputDirectory
    File outputDir

    // The class constructor sets the paths for the input and output directories.
    MyArgsProvider(FileCollection input, File output) {
        inputDir = input
        outputDir = output
    }

    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the
    // annotation processor.
    @Override
    Iterable<String> asArguments() {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        ["-AinputDir=${inputDir.singleFile.absolutePath}",
         "-AoutputDir=${outputDir.absolutePath}"]
    }
}

android {...}

Kotlin

class MyArgsProvider(
    // Annotates each directory as either an input or output for the
    // annotation processor.
    @get:InputFiles
    // Using this annotation helps Gradle determine which part of the file path
    // should be considered during up-to-date checks.
    @get:PathSensitive(PathSensitivity.RELATIVE)
    val inputDir: FileCollection,

    @get:OutputDirectory
    val outputDir: File
) : CommandLineArgumentProvider {
    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the
    // annotation processor.

    override fun asArguments(): Iterable<String> {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        return listOf("-AinputDir=${inputDir.singleFile.absolutePath}",
                      "-AoutputDir=${outputDir.absolutePath}")
    }
}

android {...}

Después de definir una clase que implemente CommandLineArgumentProvider, debes crear una instancia y pasarla al complemento de Android con el método annotationProcessorOptions.compilerArgumentProvider, como que se muestra a continuación.

Groovy

// This is in your module's build.gradle file.
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                // Creates a new MyArgsProvider object, specifies the input and
                // output paths for the constructor, and passes the object
                // to the Android plugin.
                compilerArgumentProvider new MyArgsProvider(files("input/path"),
                                         new File("output/path"))
            }
        }
    }
}

Kotlin

// This is in your module's build.gradle file.
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                // Creates a new MyArgsProvider object, specifies the input and
                // output paths for the constructor, and passes the object
                // to the Android plugin.
                compilerArgumentProvider(MyArgsProvider(files("input/path"),
                                                          file("output/path")))
            }
        }
    }
}

Para descubrir cómo la implementación de CommandLineArgumentProvider ayuda a mejorar el rendimiento de la compilación, lee Cómo almacenar proyectos de Java en caché.

Cómo inhabilitar la comprobación de errores del procesador de anotaciones

Si tienes dependencias en la ruta de clase de compilación que incluyen procesadores de anotaciones que no necesitas, puedes inhabilitar la comprobación de errores agregando lo siguiente a tu archivo build.gradle. Ten en cuenta que los procesadores de anotaciones que agregues a la ruta de clase de la compilación aún no se agregarán a la ruta de clase del procesador.

Groovy

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false
            }
        }
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                argument("includeCompileClasspath", "false")
            }
        }
    }
}

Si usas Kotlin y kapt:

Groovy

android {
    ...
    defaultConfig {
        ...
        kapt {
            includeCompileClasspath false
        }
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        kapt {
            includeCompileClasspath = false
        }
    }
}

Si experimentas problemas luego de migrar los procesadores de anotaciones de tu proyecto a la ruta de clase del procesador, puedes habilitar los procesadores de anotaciones en la ruta de clase de la compilación mediante la configuración de includeCompileClasspath en true. Sin embargo, no se recomienda configurar esta propiedad en true y la opción para hacerlo se quitará en una actualización futura del complemento de Android.

Cómo excluir dependencias transitivas

A medida que crece el alcance de una app, esta puede contener varias dependencias, incluidas las dependencias directas y las transitivas (bibliotecas de las que dependen las bibliotecas importadas de tu app). Para excluir dependencias transitivas que ya no necesitas, puedes usar la palabra clave exclude como se indica a continuación:

Groovy

dependencies {
    implementation('some-library') {
        exclude group: 'com.example.imgtools', module: 'native'
    }
}

Kotlin

dependencies {
    implementation("some-library") {
        exclude(group = "com.example.imgtools", module = "native")
    }
}

Cómo excluir dependencias transitivas de las configuraciones de pruebas

Si necesitas excluir dependencias transitivas específicas de tus pruebas, es posible que el ejemplo de código que se muestra más arriba no funcione como se espera porque una configuración de prueba (p. ej., androidTestImplementation) extiende la configuración implementation del módulo. Es decir, siempre contiene dependencias implementation cuando Gradle determina la configuración.

Entonces, si quieres excluir dependencias transitivas de tus pruebas, deberás hacerlo en el tiempo de ejecución, como se muestra a continuación:

Groovy

android.testVariants.all { variant ->
    variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}

Kotlin

android.testVariants.all {
    compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
    runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
}

Nota: De igual manera, puedes usar la palabra clave exclude en el bloque de dependencias como se muestra en el ejemplo de código original de la sección Cómo excluir dependencias transitivas a fin de omitir las que son específicas de la configuración de pruebas y que no se incluyen en otros parámetros de configuración.

Cómo configurar dependencias de apps para Wear OS

La configuración de dependencias para un módulo de Wear OS es similar a la de cualquier otro módulo. Es decir, los módulos de Wear OS usan las mismas configuraciones de dependencia, como implementation y compileOnly.

Los módulos de Wear también admiten la administración de dependencias con reconocimiento de variantes. Por lo tanto, si el módulo de tu app base tiene una dependencia en un módulo de Wear, cada variante del módulo base consumirá la variante del módulo de Wear con la que coincida. Si estás compilando una app simple con una dependencia en un solo módulo de Wear, donde el módulo configura las mismas variantes que tu módulo base, debes especificar la configuración de wearApp en el archivo build.gradle de tu módulo base, como se muestra a continuación:

Groovy


dependencies {
    // If the main and Wear app modules have the same variants,
    // variant-aware dependency management automatically matches
    // variants of the main app module with that of the Wear module.
    wearApp project(':wearable')
}

Kotlin


dependencies {
    // If the main and Wear app modules have the same variants,
    // variant-aware dependency management automatically matches
    // variants of the main app module with that of the Wear module.
    wearApp(project(":wearable"))
}

Si tienes varios módulos de Wear y quieres especificar uno diferente para cada tipo de app, puedes hacerlo mediante la configuración flavorWearApp, de la siguiente manera (no obstante, no podrás incluir otras dependencias que usen la configuración wearApp):

Groovy


dependencies {
    paidWearApp project(':wear1')
    demoWearApp project(':wear1')
    freeWearApp project(':wear2')
}

Kotlin


dependencies {
    "paidWearApp"(project(":wear1"))
    "demoWearApp"(project(":wear1"))
    "freeWearApp"(project(":wear2"))
}

Repositorios remotos

Cuando tu dependencia no es una dependencia local ni un árbol de archivos, Gradle busca los archivos en cualquier repositorio en línea que se especifique en el bloque repositories de tu archivo build.gradle. El orden en el que se enumera cada repositorio determina el orden en el que Gradle los busca para cada dependencia del proyecto. Por ejemplo, si una dependencia está disponible tanto desde el repositorio A como del B, y enumeras primero el A, Gradle descargará la dependencia del repositorio A.

De manera predeterminada, los nuevos proyectos de Android Studio especifican el repositorio Maven de Google y JCenter como ubicaciones de repositorios en el archivo build.gradle principal de tu proyecto, como se muestra a continuación:

Groovy


allprojects {
    repositories {
        google()
        jcenter()
    }
}

Kotlin


allprojects {
    repositories {
        google()
        jcenter()
    }
}

Si deseas algo del repositorio central de Maven, agrega mavenCentral(). Para un repositorio local, usa mavenLocal():

Groovy


allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        mavenLocal()
    }
}

Kotlin


allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
        mavenLocal()
    }
}

También puedes declarar repositorios Maven o Ivy específicos de la siguiente manera:

Groovy


allprojects {
    repositories {
        maven {
            url 'https://repo.example.com/maven2'
        }
        maven {
            url 'file://local/repo/'
        }
        ivy {
            url 'https://repo.example.com/ivy'
        }
    }
}

Kotlin


allprojects {
    repositories {
        maven(url = "https://repo.example.com/maven2")
        maven(url = "file://local/repo/")
        ivy(url = "https://repo.example.com/ivy")
    }
}

Para obtener más información, consulta la Guía de repositorios de Gradle.

Repositorio Maven de Google

Las versiones más recientes de las siguientes bibliotecas de Android están disponibles en el repositorio Maven de Google:

Puedes ver todos los artefactos disponibles en el índice del repositorio Maven de Google (consulta a continuación acceso programático).

Para agregar una de esas bibliotecas a tu compilación, incluye el repositorio Maven de Google en el archivo build.gradle principal:

Groovy


allprojects {
    repositories {
        google()

        // If you're using a version of Gradle lower than 4.1, you must instead use:
        // maven {
        //     url 'https://maven.google.com'
        // }
        // An alternative URL is 'https://dl.google.com/dl/android/maven2/'.
    }
}

Kotlin


allprojects {
    repositories {
        google()

        // If you're using a version of Gradle lower than 4.1, you must instead use:
        // maven {
        //     url = "https://maven.google.com"
        // }
        // An alternative URL is "https://dl.google.com/dl/android/maven2/".
    }
}

Luego, agrega la biblioteca deseada al bloque dependencies de tu módulo. Por ejemplo, la biblioteca appcompat tiene el siguiente aspecto:

Groovy


dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
}

Kotlin


dependencies {
    implementation("com.android.support:appcompat-v7:28.0.0")
}

Sin embargo, si intentas usar una versión anterior de las bibliotecas que se mencionan más arriba y se produce una falla en tu dependencia, significa que el repositorio Maven no está disponible y, en su lugar, deberás obtener la biblioteca del repositorio sin conexión.

Acceso programático

Para acceder a los artefactos Maven de Google de forma programática, puedes obtener una lista en formato XML de los grupos de artefactos en maven.google.com/master-index.xml. Para cualquier grupo, puedes ver los nombres y las versiones de bibliotecas en:

maven.google.com/group_path/group-index.xml

Por ejemplo, las bibliotecas en el grupo "android.arch.lifecycle" se enumeran en maven.google.com/android/arch/lifecycle/group-index.xml.

También puedes descargar los archivos POM y JAR en el siguiente vínculo:

maven.google.com/group_path/library/version /library-version.ext

Por ejemplo: maven.google.com/android/arch/lifecycle/compiler/1.0.0/compiler-1. 0.0.pom.

Repositorio sin conexión de SDK Manager

En el caso de las bibliotecas que no están disponibles en el repositorio Maven de Google (por lo general, las versiones anteriores de bibliotecas), deberás descargar el paquete del repositorio de Google sin conexión de SDK Manager.

Luego, podrás agregar estas bibliotecas a tu bloque dependencies como lo haces normalmente.

Las bibliotecas sin conexión se guardan en android_sdk/extras/.

Dependencias nativas con el complemento de Android para Gradle

Las bibliotecas AAR pueden contener dependencias nativas que el complemento de Android para Gradle puede consumir. AGP también puede producir AAR que expongan bibliotecas nativas a sus consumidores.

Cómo usar dependencias nativas

A partir de la versión 4.0 del complemento de Android para Gradle, es posible importar dependencias de C/C++ de AAR vinculadas a tu archivo build.gradle. Gradle las habilitará automáticamente para el sistema de compilación nativo, pero este debe estar configurado de manera tal que pueda usar las bibliotecas y los encabezados importados. Dado que las dependencias de C/C++ se distribuyen como AAR, puedes consultar los siguientes vínculos sobre AAR genéricos:

Este documento se centra en cómo configurar un sistema de compilación nativo y supone que ya agregaste una dependencia C/C++ de AAR al entorno de compilación de Gradle de tu proyecto.

Dependencias nativas en AAR

Las dependencias de AAR de tus módulos de Gradle pueden exponer bibliotecas nativas para que las use tu aplicación. Dentro del archivo AAR, el directorio de prefab contiene un paquete Prefab, que incluye los encabezados y las bibliotecas de la dependencia nativa.

Cada dependencia puede exponer como máximo un paquete Prefab, que comprenda uno o más módulos. Un módulo de Prefab es una biblioteca única, que puede ser una biblioteca compartida, estática o solo de encabezado.

Para poder usar las bibliotecas, los nombres de paquete y módulo deben ser conocidos. Por convención, el nombre del paquete coincidirá con el nombre del artefacto de Maven y el nombre del módulo coincidirá con el de la biblioteca de C/C++, pero esto no es obligatorio. Consulta la documentación de la dependencia para determinar qué nombres usa.

Configuración del sistema de compilación

La función prefab debe estar habilitada en tu módulo de Gradle para Android.

Para ello, agrega lo siguiente al bloque de android del archivo build.gradle de tu módulo:

Groovy

buildFeatures {
  prefab true
}

Kotlin

buildFeatures {
  prefab = true
}

Las dependencias importadas desde un AAR se exponen a CMake mediante CMAKE_FIND_ROOT_PATH. Gradle establecerá automáticamente ese valor cuando se invoque CMake, por lo que, si tu compilación modifica esa variable, asegúrate de adjuntarla en lugar de asignarla.

Cada dependencia expone un paquete de archivo de configuración a tu compilación, el cual se importa con el comando find_package. Ese comando busca paquetes de archivos de configuración que coincidan con el nombre y la versión del paquete específico, y expone los destinos que define para su uso en tu compilación. Por ejemplo, si tu aplicación define libapp.so y usa cURL, tu CMakeLists.txt debe incluir lo siguiente:

add_library(app SHARED app.cpp)

# Add these two lines.
find_package(curl REQUIRED CONFIG)
target_link_libraries(app curl::curl)

app.cpp ahora puede usar #include "curl/curl.h", libapp.so se vinculará automáticamente con libcurl.so cuando se compile, y libcurl.so se incluirá con la app.

Cómo publicar bibliotecas nativas en AAR

La habilidad de crear AAR nativas se agregó por primera vez en AGP 4.1.

Para exportar tus bibliotecas nativas, agrega lo siguiente al bloque android del archivo build.gradle de tu proyecto de biblioteca.

Groovy


buildFeatures {
    prefabPublishing true
}

prefab {
    mylibrary {
      headers "src/main/cpp/mylibrary/include"
    }

    myotherlibrary {
        headers "src/main/cpp/myotherlibrary/include"
    }
}

Kotlin


buildFeatures {
    prefabPublishing = true
}

prefab {
    create("mylibrary") {
      headers = "src/main/cpp/mylibrary/include"
    }

    create("myotherlibrary") {
        headers = "src/main/cpp/myotherlibrary/include"
    }
}

En este ejemplo, las bibliotecas mylibrary y myotherlibrary de tu ndk-build o compilación nativa externa de CMake se empaquetarán en el AAR que generó tu compilación, y cada una exportará los encabezados del directorio especificado a sus dependientes.

Orden de las dependencias

El orden en el que enumeras tus dependencias indica la prioridad de cada una: la primera biblioteca tendrá mayor prioridad que la segunda, la segunda tendrá mayor prioridad que la tercera, y así sucesivamente. Este orden es importante en el caso de que se combinen los recursos o se combinen los elementos del manifiesto en tu app desde las bibliotecas.

Por ejemplo, si en tu proyecto se declara lo siguiente:

  • Hay una dependencia en LIB_A y LIB_B (en ese orden).
  • Además, LIB_A depende de LIB_C y LIB_D (en ese orden).
  • LIB_B también depende de LIB_C.

Luego, el orden de la dependencia única será el siguiente:

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

De esta manera, se garantiza que tanto LIB_A como LIB_B puedan anular a LIB_C; además, LIB_D sigue teniendo mayor prioridad que LIB_B porque LIB_A (que depende de esta) tiene mayor prioridad que LIB_B.

Para descubrir cómo se fusionan los manifiestos de diferentes fuentes o dependencias de proyectos, consulta Cómo fusionar varios archivos de manifiestos.

Cómo ver las dependencias de un módulo

Algunas dependencias directas pueden tener dependencias propias, que se denominan dependencias transitivas. A fin de que no tengas que declarar manualmente cada dependencia transitiva, Gradle las reúne y agrega de forma automática. El complemento de Android para Gradle proporciona una tarea en la que se muestra una lista de las dependencias que Gradle selecciona para un módulo específico.

Para cada módulo, el informe también agrupa las dependencias que se basan en la variante de compilación, el conjunto de fuentes de prueba y la ruta de clase. A continuación, se muestra un informe de ejemplo sobre la ruta de clase de tiempo de ejecución de su variante de compilación de depuración y la ruta de clase de compilación de su conjunto de fuentes de pruebas instrumentadas del módulo de una app.

debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...

debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...

Para ejecutar la tarea, haz lo siguiente:

  1. Selecciona View > Tool Windows > Gradle (o haz clic en Gradle , en la barra de la ventana de herramientas).
  2. Expande AppName > Tasks > android y haz doble clic en androidDependencies. Una vez que Gradle ejecute la tarea, se debería abrir la ventana Run para mostrar el resultado.

Para descubrir cómo administrar dependencias en Gradle, consulta los Conceptos básicos de la administración de dependencias en la Guía del usuario de Gradle.

Cómo corregir errores de selección de dependencias

Cuando agregas varias dependencias al proyecto de tu app, es posible que se genere un conflicto entre las dependencias directas y transitivas. El complemento de Android para Gradle intenta resolver esos conflictos de manera fluida, pero es posible que algunos generen errores de tiempo de ejecución o compilación.

Para investigar qué dependencias generan estos errores, inspecciona el árbol de dependencias de tu app y busca las dependencias que aparezcan más de una vez o tengan versiones conflictivas.

Si no puedes identificar fácilmente la dependencia duplicada, intenta usar la IU de Android Studio para buscar las dependencias que incluyan la clase duplicada de la siguiente manera:

  1. Selecciona Navigate > Class en la barra de menú.
  2. En el diálogo de búsqueda emergente, asegúrate de que la casilla junto a Include non-project items esté marcada.
  3. Escribe el nombre de la clase que aparece en el error de compilación.
  4. Inspecciona los resultados de las dependencias que incluyen esa clase.

En las siguientes secciones, se describen diferentes tipos de errores de selección de dependencias que podrías experimentar y cómo corregirlos.

Cómo corregir errores de clases duplicadas

Si una clase aparece más de una vez en la ruta de clase de tiempo de ejecución, es posible que se produzca un error similar al siguiente:

Program type already present com.example.MyClass

Generalmente, este error sucede debido a una de las siguientes circunstancias:

  • Una dependencia binaria contiene una biblioteca que tu app también incluye como dependencia directa. Por ejemplo, tu app declara que depende directamente de la Biblioteca A y de la Biblioteca B, pero la Biblioteca A ya incluye la Biblioteca B en su objeto binario.
    • Para resolver este problema, quita la Biblioteca B como dependencia directa.
  • Tu app tiene una dependencia binaria local y una dependencia binaria remota en la misma biblioteca.
    • Para resolver este problema, quita una de las dependencias binarias.

Cómo corregir conflictos entre rutas de clase

Cuando Gradle determina la ruta de clase de la compilación, primero especifica la ruta de clase de tiempo de ejecución y usa el resultado para establecer qué versiones de las dependencias deberían agregarse a la ruta de clase de la compilación. En otras palabras, la ruta de clase del tiempo de ejecución determina los números de versión que se requieren para dependencias idénticas en las rutas de clase descendientes.

El classpath de tiempo de ejecución de tu app también determina los números de versión que Gradle{}require a fin de hacer coincidir las dependencias en el classpath de tiempo de ejecución para el APK{}de prueba de tu app. La jerarquía de los classpaths se describe en la figura 1.

Figura 1: Los números de versión de las dependencias que aparecen en varias rutas de clase deben coincidir según esta jerarquía

Es posible que se produzca un conflicto en el que diferentes versiones de la misma dependencia aparecen en varias rutas de clase cuando, por ejemplo, tu app incluye una versión de una dependencia que usa la configuración de dependencia implementation y un módulo de biblioteca incluye una versión diferente de la dependencia que usa la configuración runtimeOnly.

Cuando determina las dependencias en las rutas de clase de tiempo de ejecución y compilación, el complemento de Gradle para Android 3.3.0 o una versión posterior intenta corregir automáticamente conflictos entre determinadas versiones descendentes. Por ejemplo, si la ruta de clase de tiempo de ejecución incluye una biblioteca A versión 2.0 y la de compilación incluye una biblioteca A versión 1.0, el complemento actualizará la dependencia automáticamente en la ruta de clase de compilación a la versión 2.0 de la biblioteca A para evitar errores.

Sin embargo, si la ruta de clase de tiempo de ejecución incluye la versión 1.0 de la Biblioteca A y la ruta de clase de la compilación incluye la versión 2.0 de la Biblioteca A, el complemento no pasará la dependencia en la ruta de clase de compilación a la versión 1.0 de la Biblioteca A, y aun así se producirá un error similar al siguiente:

Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.

Para solucionar este problema, realiza una de las siguientes acciones:

  • Incluye la versión deseada de la dependencia como una dependencia api en tu módulo de biblioteca. Es decir, solo tu módulo de biblioteca declarará la dependencia, pero el módulo de la app también tendrá acceso a su API de manera transitiva.
  • Como alternativa, puedes declarar la dependencia en ambos módulos, pero deberías asegurarte de que cada uno use la misma versión de la dependencia. Considera configurar propiedades en todo el proyecto a fin de garantizar que las versiones de cada dependencia mantengan la coherencia en el proyecto.

Cómo aplicar la lógica de compilación personalizada

En esta sección, se describen temas avanzados que son útiles cuando quieres extender el complemento de Gradle para Android o escribir tu propio complemento.

Cómo publicar dependencias de variantes en la lógica personalizada

Una biblioteca puede tener funcionalidades que otros proyectos o subproyectos probablemente quieran usar. La publicación de una biblioteca es el proceso mediante el cual esta se habilita para sus consumidores. Las bibliotecas pueden controlar a qué dependencias pueden acceder sus consumidores en el tiempo de ejecución y compilación.

Existen dos configuraciones independientes que contienen las dependencias de cada ruta de clase que deben usar los consumidores para usar la biblioteca, como se describe a continuación:

  • variant_nameApiElements: Esta configuración contiene las dependencias transitivas que están disponibles para los consumidores durante el tiempo de compilación.
  • variant_nameRuntimeElements: Esta configuración contiene las dependencias transitivas que están disponibles para los consumidores durante el tiempo de ejecución.

Para obtener más información sobre la relación entre las diferentes opciones de configuración, ve a Opciones de configuración del complemento de biblioteca Java.

Cómo personalizar las estrategias de selección de dependencias

Un proyecto puede incluir una dependencia en dos versiones diferentes de la misma biblioteca, lo que puede generar conflictos entre las dependencias. Por ejemplo, si tu proyecto depende de la versión 1 del módulo A y la versión 2 del módulo B, y el módulo A depende de forma transitiva de la versión 3 del módulo B, se producirá un conflicto con las versiones de las dependencias.

Para resolver este conflicto, el complemento de Android para Gradle usa la siguiente estrategia de selección de dependencias: cuando el complemento detecta que hay diferentes versiones del mismo módulo en el gráfico de dependencias, selecciona de manera predeterminada la que tenga el número de versión más alto.

Sin embargo, es posible que esta estrategia no siempre funcione como lo deseas. Si quieres personalizar la estrategia de selección de dependencias, usa las siguientes opciones de configuración a fin de determinar las dependencias específicas de una variante que se necesitan para tu tarea:

  • variant_nameCompileClasspath: Esta configuración contiene la estrategia de resolución para una ruta de clase de compilación de variantes específica.
  • variant_nameRuntimeClasspath: Esta configuración contiene la estrategia de resolución para una ruta de clase de tiempo de ejecución de variantes específica.

El complemento de Gradle para Android incluye captadores que puedes usar para acceder a los objetos de configuración de cada variante. Por lo tanto, puedes usar la API de variantes para consultar la selección de la dependencia como se muestra en el siguiente ejemplo:

Groovy

android {
    applicationVariants.all { variant ->
        // Return compile configuration objects of a variant.
        variant.getCompileConfiguration().resolutionStrategy {
        // Use Gradle's ResolutionStrategy API
        // to customize how this variant resolves dependencies.
            ...
        }
        // Return runtime configuration objects of a variant.
        variant.getRuntimeConfiguration().resolutionStrategy {
            ...
        }
        // Return annotation processor configuration of a variant.
        variant.getAnnotationProcessorConfiguration().resolutionStrategy {
            ...
        }
    }
}

Kotlin

android {
    applicationVariants.all {
        // Return compile configuration objects of a variant.
        compileConfiguration.resolutionStrategy {
        // Use Gradle's ResolutionStrategy API
        // to customize how this variant resolves dependencies.
            ...
        }
        // Return runtime configuration objects of a variant.
        runtimeConfiguration.resolutionStrategy {
            ...
        }
        // Return annotation processor configuration of a variant.
        annotationProcessorConfiguration.resolutionStrategy {
            ...
        }
    }
}

Información de la dependencia de Play Console

Si compilas tu app con el AGP 4.0.0 y versiones posteriores, el complemento incluye metadatos que describen las dependencias de la biblioteca que se compilan en tu app. Cuando subes tu app, Play Console inspecciona estos metadatos con el fin de brindar alertas sobre problemas conocidos con SDK y dependencias que usa tu app y, en algunos casos, proporcionar comentarios prácticos para resolver esos problemas.

Los datos se comprimen, se encriptan con una clave de firma de Google Play y se almacenan en el bloque de firmas de tu app de lanzamiento. Recomendamos conservar este archivo de dependencias para una experiencia del usuario segura y positiva. Sin embargo, si prefieres no compartir esta información, puedes optar por no incluir el siguiente dependenciesInfo bloque en el archivo build.gradle en tu módulo:

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

Para obtener más información sobre nuestras políticas y posibles problemas con las dependencias, consulta nuestra página de asistencia para usar los SDK de terceros en tu app.