Estoy tratando de averiguar cuál es la diferencia apiy la implementationconfiguración mientras construyo mis dependencias.
En la documentación, dice que implementationtiene 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

compileaapi. 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 cambiarimplementationy 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
compilepalabra clave Gradle quedó en desuso a favor de las palabras claveapiyimplementationpara configurar las dependencias.Usar
apies el equivalente a usar lo obsoletocompile, por lo que si reemplazas todocompileconapitodo funcionará como siempre.Para comprender la
implementationpalabra clave, considere el siguiente ejemplo.EJEMPLO
Supongamos que tiene una biblioteca llamada
MyLibraryque usa internamente otra biblioteca llamadaInternalLibrary. Algo como esto:Supongamos que la configuración de
MyLibrarybuild.gradleusos es así:apidependencies{}Desea usar
MyLibraryen su código para que en su aplicaciónbuild.gradleagregue esta dependencia:Usando la
apiconfiguración (o en desusocompile) puede accederInternalLibraryen su código de aplicación:De esta manera, el módulo
MyLibraryestá potencialmente "filtrando" la implementación interna de algo. No deberías (poder) usar eso porque no lo has importado directamente.La
implementationconfiguración se introdujo para evitar esto. Entonces, si usa enimplementationlugar deapienMyLibrary: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ónMyLibraryy 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
compilecon laimplementationpalabra 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
apipara cada dependencia que sea necesaria para la API pública de su biblioteca, mientras lo usaimplementationpara 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áInternalLibraryeliminado. ¿Cuál es la mejor práctica para que las bibliotecas de Android se utilicen en las aplicaciones ProGuard?Me gusta pensar en una
apidependencia como pública (vista por otros módulos) mientras que laimplementationdependencia como privada (solo vista por este módulo).Tenga en cuenta que, a diferencia de
public/privatevariables y métodos,api/implementationdependencias no se aplican por el tiempo de ejecución. Esto es simplemente una optimización en tiempo de construcción, que permiteGradlesaber qué módulos necesita recompilar cuando una de las dependencias cambia su API.fuente
apidependencias en el ámbito de "compilación" (se incluirán como dependencias en su biblioteca y todo lo que dependa de su biblioteca) yimplementationdependencias 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).implementationpara 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
appmódulo que se usalib1como biblioteca y que selib1usalib2como biblioteca. Algo como esto:app -> lib1 -> lib2.Ahora, cuando se usa
api lib2inlib1,apppuede ver loslib2códigos cuando se usa:api lib1oimplementation lib1en elappmódulo.PERO cuando se usa
implementation lib2enlib1, entoncesappno puede ver loslib2có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 dependenciescomando 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 dependenciescomando 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