tl; dr
Solo reemplace:
compile
con implementation
(si no necesita transitividad) o api
(si necesita transitividad)
testCompile
con testImplementation
debugCompile
con debugImplementation
androidTestCompile
con androidTestImplementation
compileOnly
aun es válido. Fue agregado en 3.0 para reemplazar provisto y no compilar. ( provided
introducido cuando Gradle no tenía un nombre de configuración para ese caso de uso y lo nombró por el alcance proporcionado por Maven).
Es uno de los cambios importantes que viene con Gradle 3.0 que Google anunció en IO17 .
La compile
configuración ahora está en desuso y debe reemplazarse por implementation
oapi
De la documentación de Gradle :
dependencies {
api 'commons-httpclient:commons-httpclient:3.1'
implementation 'org.apache.commons:commons-lang3:3.5'
}
Las dependencias que aparecen en las api
configuraciones estarán expuestas de forma transitiva a los consumidores de la biblioteca y, como tales, aparecerán en la compilación classpath de los consumidores.
Las dependencias encontradas en la implementation
configuración, por otro lado, no estarán expuestas a los consumidores y, por lo tanto, no se filtrarán en la ruta de compilación de los consumidores. Esto viene con varios beneficios:
- las dependencias ya no se filtran en el classpath de compilación de los consumidores, por lo que nunca dependerá accidentalmente de una dependencia transitiva
- compilación más rápida gracias al tamaño reducido de classpath
- menos recompilaciones cuando cambian las dependencias de implementación: los consumidores no necesitarían ser recompilados
- Publicación más limpia: cuando se usa junto con el nuevo complemento de publicación de Maven, las bibliotecas Java producen archivos POM que distinguen exactamente entre lo que se requiere para compilar contra la biblioteca y lo que se requiere para usar la biblioteca en tiempo de ejecución (en otras palabras, no mezclar lo que se necesita para compilar la biblioteca en sí y lo que se necesita para compilar contra la biblioteca).
Todavía existe la configuración de compilación, pero no se debe utilizar, ya que no ofrece las garantías de que los api
y implementation
las configuraciones proporcionan.
Nota: si solo está utilizando una biblioteca en el módulo de su aplicación, el caso común, no notará ninguna diferencia.
solo verá la diferencia si tiene un proyecto complejo con módulos que dependen uno del otro, o si está creando una biblioteca.
implementation
ocultar la dependencia. ¿Mi pregunta tiene sentido?implementation
solo x api estará expuesto, pero si usaapi
y, z también estará expuesto.Esta respuesta va a demostrar la diferencia entre
implementation
,api
ycompile
en un proyecto.Digamos que tengo un proyecto con tres módulos Gradle:
app
tienemyandroidlibrary
como dependencias.myandroidlibrary
tienemyjavalibrary
como dependencias.myjavalibrary
tiene unaMySecret
clasemyandroidlibrary
tiene unaMyAndroidComponent
clase que manipula el valor de laMySecret
clase.Por último,
app
solo le interesa el valor demyandroidlibrary
Ahora, hablemos de las dependencias ...
app
necesita consumir:myandroidlibrary
, así que enapp
build.gradle usoimplementation
.( Nota : también puedes usar api / compile. Pero mantén ese pensamiento por un momento).
¿Cómo crees que
myandroidlibrary
debería ser build.gradle? ¿Qué alcance debemos usar?Tenemos tres opciones:
Compilar o API (opción # 2 o # 3)
Si estás usando
compile
oapi
. Nuestra aplicación de Android ahora puede acceder a lamyandroidcomponent
dependencia, que es unaMySecret
clase.Implementación (opción # 1)
Si está utilizando la
implementation
configuración,MySecret
no está expuesto.Entonces, ¿qué configuración debe elegir? Eso realmente depende de su requerimiento.
Si desea exponer dependencias use
api
ocompile
.Si no desea exponer dependencias (ocultar su módulo interno), use
implementation
.Nota:
Esto es solo una esencia de las configuraciones de Gradle, consulte la Tabla 49.1. Complemento de la Biblioteca Java: configuraciones utilizadas para declarar dependencias para una explicación más detallada.
El proyecto de muestra para esta respuesta está disponible en https://github.com/aldoKelvianto/ImplementationVsCompile
fuente
compile
no garantiza las mismas cosas queapi
garantiza.Compile
la configuración quedó en desuso y debería reemplazarse porimplementation
oapi
.Puede leer los documentos en https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation .
La breve parte es-
Para más explicaciones, consulte esta imagen.
fuente
Breve solución:
El mejor enfoque es reemplazar todas las
compile
dependencias conimplementation
dependencias. Y solo cuando pierda la interfaz de un módulo, debe usarapi
. Eso debería causar mucha menos recompilación.Explica más:
Antes de Android Gradle plugin 3.0 : tuvimos un gran problema, un cambio de código hace que todos los módulos se vuelvan a compilar. La causa raíz de esto es que Gradle no sabe si se pierde la interfaz de un módulo a través de otro o no.
Después del complemento Android Gradle 3.0 : el último complemento Android Gradle ahora requiere que defina explícitamente si pierde la interfaz de un módulo. En base a eso, puede tomar la decisión correcta sobre lo que debería compilar.
Como tal, la
compile
dependencia ha quedado en desuso y ha sido reemplazada por dos nuevas:api
: pierde la interfaz de este módulo a través de su propia interfaz, lo que significa exactamente lo mismo que la antiguacompile
dependenciaimplementation
: solo usa este módulo internamente y no lo filtra a través de su interfazEntonces, ahora puede decirle explícitamente a Gradle que recompile un módulo si la interfaz de un módulo usado cambia o no.
Cortesía del blog de Jeroen Mols.
fuente
fuente
implementation
seguido por aruntime
.La breve diferencia en el término de laico es:
lea la respuesta de @aldok para obtener un ejemplo completo.
fuente
Desde la versión 5.6.3, la documentación de Gradle proporciona reglas básicas simples para identificar si una
compile
dependencia antigua (o una nueva) debe reemplazarse con unaimplementation
o unaapi
dependencia:fuente
Gradle 3.0
introdujo los siguientes cambios:compile
->api
api
la palabra clave es la misma que en desusocompile
compile
->implementation
Es preferible porque tiene algunas ventajas.
implementation
exponer la dependencia solo para un nivel superior en el momento de la compilación (la dependencia está disponible en tiempo de ejecución). Como resultado, tiene una compilación más rápida (no es necesario volver a compilar los consumidores que son superiores a 1 nivel)provided
->compileOnly
Esta dependencia solo está disponible en tiempo de compilación (la dependencia no está disponible en tiempo de ejecución). Esta dependencia no puede ser transitiva y ser
.aar
. Se puede usar con el procesador de anotaciones en tiempo de compilación y le permite reducir un archivo de salida finalcompile
->annotationProcessor
Muy similar
compileOnly
pero también garantiza que la dependencia transitiva no sea visible para el consumidorapk
->runtimeOnly
La dependencia no está disponible en tiempo de compilación pero está disponible en tiempo de ejecución.
fuente
api = public
,implementation = internal
ycompileOnly = private
- que necesito para crear este tipo de alias para estas funciones, ya que son confusas súper.