J'essaie de comprendre quelle est la différence entre api
et la implementation
configuration lors de la construction de mes dépendances.
Dans la documentation, il est dit que le implementation
temps de construction est meilleur, mais, en voyant ce commentaire dans une question similaire, je me demande si c'est vrai.
Étant donné que je ne suis pas un expert du gradle, j'espère que quelqu'un pourra vous aider. J'ai déjà lu la documentation mais je me demandais une explication facile à comprendre.
android
gradle
dependencies
implementation
reinaldomoreira
la source
la source
compile
àapi
. Les bibliothèques que vous utilisez en interne peuvent utiliser des implémentations privées qui ne sont pas exposées dans la bibliothèque finale afin qu'elles soient transparentes pour vous. Ces dépendances "internes-privées" peuvent être commutéesimplementation
et lorsque le plugin Android Gradle compilera votre application, il ignorera la compilation de ces dépendances, ce qui réduira le temps de construction (mais ces dépendances seront disponibles au moment de l'exécution). Évidemment, vous pouvez faire la même chose si vous avez des bibliothèques de modules localesRéponses:
Le
compile
mot clé Gradle a été déconseillé au profit des mots clésapi
etimplementation
pour configurer les dépendances.Utiliser
api
équivaut à utiliser le obsolètecompile
, donc si vous remplacez toutcompile
parapi
tout, cela fonctionnera comme toujours.Pour comprendre le
implementation
mot - clé, considérons l'exemple suivant.EXEMPLE
Supposons que vous ayez une bibliothèque appelée
MyLibrary
qui utilise en interne une autre bibliothèque appeléeInternalLibrary
. Quelque chose comme ça:Supposons que la configuration
MyLibrary
build.gradle
utilise comme ceci:api
dependencies{}
Vous voulez utiliser
MyLibrary
dans votre code donc dans votre applicationbuild.gradle
vous ajoutez cette dépendance:En utilisant la
api
configuration (ou obsolètecompile
), vous pouvez accéderInternalLibrary
dans votre code d'application:De cette façon, le module
MyLibrary
«fuit» potentiellement l'implémentation interne de quelque chose. Vous ne devriez pas (pouvoir) l'utiliser car il n'est pas directement importé par vous.La
implementation
configuration a été introduite pour éviter cela. Alors maintenant, si vous utilisezimplementation
au lieu deapi
dansMyLibrary
:vous ne pourrez plus appeler
InternalLibrary.giveMeAString()
votre code d'application.Ce type de stratégie de boxe permet au plugin Android Gradle de savoir que si vous modifiez quelque chose
InternalLibrary
, il ne doit déclencher que la recompilationMyLibrary
et non la recompilation de l'ensemble de votre application, car vous n'y avez pas accèsInternalLibrary
.Lorsque vous avez beaucoup de dépendances imbriquées, ce mécanisme peut accélérer considérablement la construction. (Regardez la vidéo liée à la fin pour une compréhension complète de cela)
CONCLUSIONS
Lorsque vous passez au nouveau plugin Android Gradle 3.XX, vous devez remplacer tous vos fichiers
compile
par leimplementation
mot - clé (1 *) . Essayez ensuite de compiler et de tester votre application. Si tout va bien, laissez le code tel quel, si vous avez des problèmes, vous avez probablement un problème avec vos dépendances ou vous avez utilisé quelque chose qui est maintenant privé et qui n'est pas plus accessible. Suggestion par l'ingénieur du plugin Android Gradle Jerome Dochez (1 ) * )Si vous êtes un responsable de bibliothèque, vous devez utiliser
api
pour chaque dépendance qui est nécessaire pour l'API publique de votre bibliothèque, tandis queimplementation
pour les dépendances de test ou les dépendances qui ne doivent pas être utilisées par les utilisateurs finaux.Article utile présentant la différence entre l' implémentation et l' API
RÉFÉRENCES (Il s'agit de la même vidéo divisée pour gagner du temps)
Google I / O 2017 - Comment accélérer la construction de Gradle (FULL VIDEO)
Google I / O 2017 - Comment accélérer la construction de Gradle (NOUVEAU GRADLE PLUGIN 3.0.0 PART UNIQUEMENT)
Google I / O 2017 - Comment accélérer la construction de Gradle (référence à 1 * )
Documentation Android
la source
MyLibrary#myString()
se bloquera car ProGuard aura étéInternalLibrary
supprimé. Quelle est la meilleure pratique pour les bibliothèques Android à utiliser dans les applications ProGuard?J'aime penser une
api
dépendance comme publique (vue par d'autres modules) tandis que laimplementation
dépendance est privée (vue seulement par ce module).Notez que, contrairement aux
public
/private
variables et aux méthodes,api
/ lesimplementation
dépendances ne sont pas appliquées par le runtime. Il s'agit simplement d'une optimisation au moment de la construction, qui permetGradle
de savoir de quels modules il a besoin pour recompiler lorsque l'une des dépendances change son API.la source
api
dépendances dans la portée "compiler" (elles seront incluses en tant que dépendances dans votre bibliothèque et tout ce qui dépend de votre bibliothèque) et lesimplementation
dépendances dans la portée "runtime" (il vaut mieux être sur le classpath lorsque votre code est en cours d'exécution, mais ils ne sont pas nécessaires pour compiler un autre code qui utilise votre bibliothèque).implementation
pour toute dépendance nécessaire à l'exécution (et pour votre bibliothèque à compiler), mais cela ne doit pas être automatiquement tiré dans des projets qui utilisent votre bibliothèque. Un exemple serait jax-rs, votre bibliothèque pourrait utiliser RESTeasy, mais elle ne devrait pas extraire ces bibliothèques dans un projet qui utilise votre bibliothèque, car elles pourraient vouloir utiliser Jersey à la place.Considérez que vous avez un
app
module qui utiliselib1
comme bibliothèque etlib1
utiliselib2
comme bibliothèque. Quelque chose comme ceci:app -> lib1 -> lib2
.Maintenant, lorsque vous utilisez
api lib2
danslib1
, vousapp
pouvez voir leslib2
codes lorsque vous utilisez:api lib1
ouimplementation lib1
dans leapp
module.MAIS lors de l'utilisation
implementation lib2
danslib1
,app
ne peut pas voir leslib2
codes.la source
Réponses de @matpag et @ dev-bmax sont suffisamment claires pour faire comprendre aux utilisateurs les différents usages entre l'implémentation et l'API. Je veux juste faire une explication supplémentaire sous un autre angle, espère aider les gens qui ont la même question.
J'ai créé deux projets à tester:
La hiérarchie des dépendances décrite ci-dessus ressemble à:
[project-b] -> [project-a] -> [spring-boot-gradle-plugin]
J'ai ensuite testé les scénarios suivants:
Faire le projet A dépend de 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' par l' implémentation .
Exécutez la
gradle dependencies
commande dans un terminal dans le répertoire racine poject B , avec la capture d'écran suivante de la sortie, nous pouvons voir que 'spring-boot-gradle-plugin' apparaît dans l'arbre des dépendances de runtimeClasspath, mais pas dans celui de compileClasspath, je pense que c'est exactement pourquoi nous ne pouvons pas faire utilisation de la bibliothèque qui a déclaré utiliser l'implémentation, elle ne le sera tout simplement pas par compilation.Faire un projet A dépend de 'org.springframework.boot: spring-boot-gradle-plugin: 1.5.20.RELEASE' par api
Exécutez à nouveau la
gradle dependencies
commande dans un terminal dans le répertoire racine de poject B. Maintenant, 'spring-boot-gradle-plugin' apparaît à la fois dans l'arborescence des dépendances compileClasspath et runtimeClasspath.Une différence significative que j'ai remarquée est que la dépendance dans le projet producteur / bibliothèque déclarée de manière implémentée n'apparaîtra pas dans compileClasspath des projets consommateurs, de sorte que nous ne pouvons pas utiliser la bibliothèque correspondante dans les projets consommateurs.
la source
De la documentation Gradle :
Voyons un script de construction très simple pour un projet basé sur JVM.
la source