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
del archivo build.gradle
de tu módulo.
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 archivosettings.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 archivobuild.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).
Si necesitas una dependencia de AGP durante el tiempo de compilación, asegúrate de agregarla como una dependencia explícita. Dado que AGP usa configuraciones api/implementation
internamente, es posible que se quiten algunos artefactos de la ruta de clase de la compilación, y esta podría cambiar.
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 esta página.
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 tu compilación nativa. En esta página, consulta Cómo usar dependencias nativas.
Configuraciones de dependencias
Dentro del bloque dependencies
, puedes declarar una dependencia de biblioteca con 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 para 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 tiempo 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 |
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 |
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
Nota: No puedes usar la configuración |
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 con la configuración El complemento de Android para Gradle entiende que una dependencia es un procesador de anotaciones si su archivo JAR contiene el siguiente archivo:
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 |
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 .
Groovydependencies { // 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') } Kotlindependencies { // 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")) } |
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. Esta configuración dejó de estar disponible (está disponible en AGP 1.0-4.2). |
compile
|
Gradle agrega la dependencia a la ruta de clase y al resultado de la compilación, y la exporta a otros módulos. Esta configuración dejó de estar disponible (está disponible en AGP 1.0-4.2). |
provided
|
Gradle solo agrega la dependencia a la ruta de clase de la compilación (pero no al resultado). Esta configuración dejó de estar disponible (está disponible en AGP 1.0-4.2). |
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.5.1' }
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.5.1") }
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, puedes 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é si se aplican 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 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 si agregas 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.
Repositorios remotos
Cuando tu dependencia no es una biblioteca o un árbol de archivos local, Gradle busca los archivos en cualquier repositorio en línea que se especifique en el bloque dependencyResolutionManagement { repositories {...} }
de tu archivo settings.gradle
.
El orden en el que se enumera cada repositorio determina el orden en el que Gradle busca en ellos 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 forma predeterminada, los nuevos proyectos de Android Studio especifican el repositorio Maven de Google y el repositorio central de Maven como ubicaciones de repositorio en el archivo settings.gradle
del proyecto, como se muestra a continuación:
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Si deseas algo de un repositorio local, usa mavenLocal()
:
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() mavenLocal() } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() mavenLocal() } }
También puedes declarar repositorios Maven o Ivy específicos de la siguiente manera:
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url 'https://repo.example.com/maven2' } maven { url 'file://local/repo/' } ivy { url 'https://repo.example.com/ivy' } } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 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:
- Bibliotecas de AndroidX
- Biblioteca de componentes de arquitectura
- Biblioteca de diseño de restricciones
- Prueba de AndroidX
- Biblioteca de vinculación de datos
- Biblioteca de Apps instantáneas Android
- Wear OS
- Servicios de Google Play
- Biblioteca de Facturación Google Play
- Firebase
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
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 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
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 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.6.1' }
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 AARs que expongan bibliotecas nativas para 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:
- En Cómo crear una biblioteca de Android, obtén documentación sobre los AAR genéricos y cómo integrarlos a tu proyecto, sobre todo cuando deseas usar AAR como una dependencia C/C++ local.
- En Cómo agregar dependencias de compilación, obtén información para agregar dependencias a tu archivo
build.gradle
, en especial las remotas.
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 }
De manera opcional, configura una versión en el archivo gradle.properties
de tu proyecto:
android.prefabVersion=2.0.0
Por lo general, la versión predeterminada seleccionada en AGP se ajusta a tus necesidades. Solo debes seleccionar una versión diferente si hay un error que debes solucionar o una función nueva que te interesa.
Cada dependencia expone un archivo Android.mk
a tu compilación, el cual se importa con el comando import-module. Este comando busca archivos Android.mk
con la ruta de acceso determinada dentro de los directorios de importación de la compilación (según lo configurado por import-add-path
) y expone los módulos que define para su uso en tu compilación. Por ejemplo, si tu aplicación define libapp.so
y usa cURL, tu archivo Android.mk
debe incluir lo siguiente:
include $(CLEAR_VARS)
LOCAL_MODULE := libapp
LOCAL_SRC_FILES := app.cpp
LOCAL_SHARED_LIBRARIES := curl
include $(BUILD_SHARED_LIBRARY)
# If you don't need your project to build with NDKs older than r21, you can omit
# this block.
ifneq ($(call ndk-major-at-least,21),true)
$(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH))
endif
$(call import-module,prefab/curl)
Ten en cuenta que el elemento import-add-path
explícito solo es necesario cuando se usan NDK antes de r21. A partir de la versión r21, NDK_GRADLE_INJECTED_IMPORT_PATH
se agregará automáticamente a las rutas de acceso de importación.
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
yLIB_B
(en ese orden). - Además,
LIB_A
depende deLIB_C
yLIB_D
(en ese orden). LIB_B
también depende deLIB_C
.
Luego, el orden de la dependencia única será el siguiente:
LIB_A
LIB_D
LIB_B
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:
- Selecciona View > Tool Windows > Gradle (o haz clic en Gradle
, en la barra de la ventana de herramientas).
- 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:
- Selecciona Navigate > Class en la barra de menú.
- En el diálogo de búsqueda emergente, asegúrate de que la casilla junto a Include non-project items esté marcada.
- Escribe el nombre de la clase que aparece en el error de compilación.
- 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 SDKs de terceros en tu app.
Estadísticas de SDKs
Android Studio muestra advertencias de lint en los archivos build.gradle
y en el diálogo Project Structure para los SDKs públicos que sus autores marcaron como desactualizados en el Índice SDK de Google Play. Este es un indicador para actualizar esas dependencias, ya que usar versiones desactualizadas podría impedir que publiques contenido en Google Play Console en el futuro.