J'essaie de comprendre quelle est la différence entre api
et implementation
de configuration lors de la construction de mes dépendances.
Dans la documentation, il est dit qu' implementation
a un meilleur moment de la construction, mais,
en voyant ce commentaire dans une question similaire, je suis arrivé à me demander si c'est vrai.
Depuis que je ne suis pas expert dans gradle, j'espère que quelqu'un peut vous aider. J'ai lu la documentation déjà, mais je me demandais sur un facile-à-comprendre l'explication.
Réponses
Trop de publicités?Gradle compile
mot-clé a été dépréciée en faveur de l' api
et implementation
mots clés pour configurer les dépendances.
À l'aide de api
est équivalente à l'utilisation de l'obsolète compile
, donc si vous remplacez tous les compile
avec api
tout fonctionne comme toujours.
Pour comprendre l' implementation
mot-clé considérons l'exemple suivant.
EXEMPLE
Supposons que vous avez une bibliothèque appelée MyLibrary
qui utilise en interne une autre bibliothèque appelée InternalLibrary
. Quelque chose comme ceci:
// 'InternalLibrary' module
public class InternalLibrary {
public static String giveMeAString(){
return "hello";
}
}
// 'MyLibrary' module
public class MyLibrary {
public String myString(){
return InternalLibrary.giveMeAString();
}
}
Supposons que l' MyLibrary
build.gradle
utilise api
configuration en dependencies{}
comme ceci:
dependencies {
api project(':InternalLibrary')
}
Vous souhaitez utiliser MyLibrary
dans votre code dans votre application build.gradle
vous ajouter cette dépendance:
dependencies {
api project(':MyLibrary')
}
À l'aide de l' api
de configuration (ou obsolète compile
), vous pouvez accéder à la fois MyLibrary
et InternalLibrary
dans le code de votre application:
// Access 'MyLibrary' (as desired and expected)
MyLibrary myLib = new MyLibrary();
System.out.println(myLib.myString());
// Can ALSO access the internal library too (and you shouldn't)
System.out.println(InternalLibrary.giveMeAString());
De cette manière, le module MyLibrary
est potentiellement une "fuite" de la mise en œuvre interne de quelque chose. Vous ne devriez pas (être capable de) l'utiliser car il n'est pas importés directement par vous.
L' implementation
configuration a été introduit pour éviter cela.
Alors maintenant, si vous utilisez implementation
au lieu de api
en MyLibrary
:
dependencies {
implementation project(':InternalLibrary')
}
Et dans votre application build.gradle
:
dependencies {
implementation project(':MyLibrary')
}
vous ne serez pas en mesure d'appeler InternalLibrary.giveMeAString()
dans votre application code plus.
Notez que si MyLibrary
utilise api
à l'importation InternalLibrary
, votre application SERA en mesure d'appeler InternalLibrary.giveMeAString()
sans problème, indépendant de l'utilisation de api
ou implementation
ajouter MyLibrary
de votre application.
Cette sorte de boxe stratégie permet à l'Android plugin Gradle de savoir que si vous modifiez quelque chose en InternalLibrary
pour déclencher la recompilation de l' MyLibrary
seulement et de ne pas déclencher la recompilation de l'ensemble de votre application car vous n'avez pas accès à l' InternalLibrary
.
Lorsque vous avez beaucoup de imbriqués les dépendances de ce mécanisme peut accélérer la construction d'un beaucoup. (Regardez la vidéo, liée à la fin pour une pleine compréhension de ce)
CONCLUSIONS
Lorsque vous basculez vers la nouvelle Android plugin Gradle 3.X.X, vous devez remplacer tous vos
compile
avec l'implementation
mot-clé (1*). Ensuite, essayez de compiler et de tester votre application. Si tout est ok de laisser le code en l'état, si vous avez des problèmes, vous avez probablement quelque chose de mal avec vos dépendances ou vous avez utilisé quelque chose qui maintenant est privée et n'est pas plus accessible. Suggestion Android plugin Gradle ingénieur Jérôme Dochez (1)*)Si vous êtes une bibliothèque mantainer vous devez utiliser
api
pour chaque dépendance qui est nécessaire pour l'API publique de votre bibliothèque, alors que l'utilisationimplementation
pour le test des dépendances ou des dépendances qui ne doit pas être utilisé par les utilisateurs finaux.
Utile de l'article Présentant la différence entre la mise en œuvre et de l'api
RÉFÉRENCES (C'est la même vidéo découpée en place pour un gain de temps)
Google I/O 2017 - Comment accélérer Gradle construit (VIDÉO COMPLÈTE)
Google I/O 2017 - Comment accélérer Gradle construit (NOUVEAU PLUGIN GRADLE 3.0.0 PARTIE SEULEMENT)
Google I/O 2017 - Comment accélérer Gradle construit (référence à 1*)
J'aime penser à un api
de la dépendance publique (visible par les autres modules), tandis que implementation
de la dépendance privée (seulement vu par le présent module).
Notez que contrairement aux public
/private
de variables et de méthodes, api
/implementation
les dépendances ne sont pas appliquées par le runtime. Ce n'est qu'un moment de la construction, l'optimisation, qui permet d' Gradle
savoir quels modules il a besoin de recompiler lorsque l'une des dépendances de l'évolution de ses API.
Considérez que vous avez app
module qui utilise lib1
que d'une bibliothèque et d' lib1
utilise lib2
comme une bibliothèque. Quelque chose comme ceci: app -> lib1 -> lib2
.
Maintenant, lors de l'utilisation d' api lib2
en lib1
, alors app
pouvez le voir lib2
codes lors de l'utilisation: api lib1
ou implementation lib1
dans la app
module.
MAIS lors de l'utilisation d' implementation lib2
en lib1
, alors app
ne peuvent pas voir l' lib2
codes.