Estoy tratando de averiguar cuál es la diferencia api
y la implementation
configuración mientras construyo mis dependencias.
En la documentación, dice que implementation
tiene un mejor tiempo de compilación, pero al ver este comentario en una pregunta similar, me pregunto si es cierto.
Como no soy un experto en gradle, espero que alguien pueda ayudar. Ya leí la documentación pero me preguntaba acerca de una explicación fácil de entender.
android
gradle
dependencies
implementation
reinaldomoreira
fuente
fuente
compile
aapi
. Las bibliotecas que usa internamente podrían usar algunas implementaciones privadas que no están expuestas en la biblioteca final, por lo que son transparentes para usted. Esas dependencias "internas-privadas" se pueden cambiarimplementation
y cuando el complemento de gradle de Android compile su aplicación, omitirá la compilación de esas dependencias, lo que dará como resultado un tiempo de compilación menor (pero esas dependencias estarán disponibles en tiempo de ejecución). Obviamente, puede hacer lo mismo si tiene bibliotecas de módulos localesRespuestas:
La
compile
palabra clave Gradle quedó en desuso a favor de las palabras claveapi
yimplementation
para configurar las dependencias.Usar
api
es el equivalente a usar lo obsoletocompile
, por lo que si reemplazas todocompile
conapi
todo funcionará como siempre.Para comprender la
implementation
palabra clave, considere el siguiente ejemplo.EJEMPLO
Supongamos que tiene una biblioteca llamada
MyLibrary
que usa internamente otra biblioteca llamadaInternalLibrary
. Algo como esto:Supongamos que la configuración de
MyLibrary
build.gradle
usos es así:api
dependencies{}
Desea usar
MyLibrary
en su código para que en su aplicaciónbuild.gradle
agregue esta dependencia:Usando la
api
configuración (o en desusocompile
) puede accederInternalLibrary
en su código de aplicación:De esta manera, el módulo
MyLibrary
está potencialmente "filtrando" la implementación interna de algo. No deberías (poder) usar eso porque no lo has importado directamente.La
implementation
configuración se introdujo para evitar esto. Entonces, si usa enimplementation
lugar deapi
enMyLibrary
:ya no podrá llamar
InternalLibrary.giveMeAString()
a su código de aplicación.Este tipo de estrategia de boxeo le permite al complemento Android Gradle saber que si edita algo
InternalLibrary
, solo debe activar la recompilaciónMyLibrary
y no la recompilación de toda su aplicación, porque no tiene acceso a ellaInternalLibrary
.Cuando tiene muchas dependencias anidadas, este mecanismo puede acelerar mucho la compilación. (Mire el video vinculado al final para obtener una comprensión completa de esto)
CONCLUSIONES
Cuando cambie al nuevo complemento Android Gradle 3.XX, debe reemplazar todo
compile
con laimplementation
palabra clave (1 *) . Luego intente compilar y probar su aplicación. Si todo está bien, deje el código como está, si tiene problemas, probablemente tenga algo mal con sus dependencias o haya utilizado algo que ahora es privado y no más accesible. Sugerencia del ingeniero del complemento Android Gradle Jerome Dochez (1 ) * )Si usted es un mantenedor de la biblioteca, debe usarlo
api
para cada dependencia que sea necesaria para la API pública de su biblioteca, mientras lo usaimplementation
para probar dependencias o dependencias que no deben ser utilizadas por los usuarios finales.Artículo útil que muestra la diferencia entre la implementación y la API
REFERENCIAS (Este es el mismo video dividido para ahorrar tiempo)
Google I / O 2017: cómo acelerar las compilaciones de Gradle (VIDEO COMPLETO)
Google I / O 2017 - Cómo acelerar las compilaciones de Gradle (NUEVA PARTE GRADLE PLUGIN 3.0.0 SOLAMENTE)
Google I / O 2017: cómo acelerar las compilaciones de Gradle (referencia a 1 * )
Documentación de Android
fuente
MyLibrary#myString()
se bloqueará porque ProGuard se habráInternalLibrary
eliminado. ¿Cuál es la mejor práctica para que las bibliotecas de Android se utilicen en las aplicaciones ProGuard?Me gusta pensar en una
api
dependencia como pública (vista por otros módulos) mientras que laimplementation
dependencia como privada (solo vista por este módulo).Tenga en cuenta que, a diferencia de
public
/private
variables y métodos,api
/implementation
dependencias no se aplican por el tiempo de ejecución. Esto es simplemente una optimización en tiempo de construcción, que permiteGradle
saber qué módulos necesita recompilar cuando una de las dependencias cambia su API.fuente
api
dependencias en el ámbito de "compilación" (se incluirán como dependencias en su biblioteca y todo lo que dependa de su biblioteca) yimplementation
dependencias en el ámbito de "tiempo de ejecución" (es mejor que estén en el classpath cuando su código se está ejecutando, pero no son necesarios para compilar otro código que use su biblioteca).implementation
para cualquier dependencia que sea necesaria para ejecutar (y para que su biblioteca se compile), pero eso no debería ser automáticamente incorporado a los proyectos que usan su biblioteca. Un ejemplo sería jax-rs, su biblioteca podría usar RESTeasy, pero no debería arrastrar esas librerías a ningún proyecto que use su biblioteca, ya que podrían querer usar Jersey en su lugar.Considere que tiene un
app
módulo que se usalib1
como biblioteca y que selib1
usalib2
como biblioteca. Algo como esto:app -> lib1 -> lib2
.Ahora, cuando se usa
api lib2
inlib1
,app
puede ver loslib2
códigos cuando se usa:api lib1
oimplementation lib1
en elapp
módulo.PERO cuando se usa
implementation lib2
enlib1
, entoncesapp
no puede ver loslib2
códigos.fuente
Las respuestas de @matpag y @ dev-bmax son lo suficientemente claras como para que las personas entiendan los diferentes usos entre la implementación y la API. Solo quiero hacer una explicación adicional desde otro ángulo, espero ayudar a las personas que tienen la misma pregunta.
Creé dos proyectos para probar:
La jerarquía de dependencias descrita anteriormente se ve así:
[proyecto-b] -> [proyecto-a] -> [plugin spring-boot-gradle-plugin]
Luego probé los siguientes escenarios:
Hacer el proyecto A depende de 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' por implementación .
Ejecute el
gradle dependencies
comando en un terminal en el directorio raíz del objeto B, con la siguiente captura de pantalla de salida podemos ver que 'spring-boot-gradle-plugin' aparece en el árbol de dependencias runtimeClasspath, pero no en compileClasspath's, creo que es exactamente por eso que no podemos hacer uso de la biblioteca que declaró usar la implementación, simplemente no lo hará a través de la compilación.Hacer que el proyecto A dependa de 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' por api
Ejecute el
gradle dependencies
comando en una terminal en el directorio raíz del objeto B nuevamente. Ahora aparece 'spring-boot-gradle-plugin' en el árbol de dependencias compileClasspath y runtimeClasspath.Una diferencia significativa que noté es que la dependencia en el proyecto productor / biblioteca declarada en forma de implementación no aparecerá en compileClasspath de proyectos de consumo, por lo que no podemos hacer uso de la lib correspondiente en los proyectos de consumo.
fuente
De la documentación de gradle :
Echemos un vistazo a un script de compilación muy simple para un proyecto basado en JVM.
fuente