tl; dr
Remplacez simplement:
compile
avec implementation
(si vous n'avez pas besoin de transitivité) ou api
(si vous avez besoin de transitivité)
testCompile
avec testImplementation
debugCompile
avec debugImplementation
androidTestCompile
avec androidTestImplementation
compileOnly
est toujours valide. Il a été ajouté en 3.0 pour remplacer fourni et ne pas compiler. ( provided
introduit lorsque Gradle n'avait pas de nom de configuration pour ce cas d'utilisation et le nommait d'après la portée fournie par Maven.)
C'est l'un des changements les plus marquants de Gradle 3.0 que Google a annoncé à IO17 .
La compile
configuration est désormais obsolète et doit être remplacée par implementation
ouapi
De la documentation Gradle :
dependencies {
api 'commons-httpclient:commons-httpclient:3.1'
implementation 'org.apache.commons:commons-lang3:3.5'
}
Les dépendances apparaissant dans les api
configurations seront transitoirement exposées aux consommateurs de la bibliothèque, et en tant que telles apparaîtront sur le chemin de classe de compilation des consommateurs.
Les dépendances trouvées dans la implementation
configuration, en revanche, ne seront pas exposées aux consommateurs, et ne fuiront donc pas dans le chemin de classe de compilation des consommateurs. Cela comporte plusieurs avantages:
- les dépendances ne s'infiltrent plus dans le chemin de classe de compilation des consommateurs, vous ne dépendrez donc jamais accidentellement d'une dépendance transitive
- compilation plus rapide grâce à une taille de chemin de classe réduite
- moins de recompilations lorsque les dépendances d'implémentation changent: les consommateurs n'auraient pas besoin d'être recompilés
- publication plus propre: lorsqu'elles sont utilisées en conjonction avec le nouveau plugin maven-publish, les bibliothèques Java produisent des fichiers POM qui distinguent exactement ce qui est nécessaire pour compiler avec la bibliothèque et ce qui est requis pour utiliser la bibliothèque au moment de l'exécution (en d'autres termes, ne le faites pas mélanger ce qui est nécessaire pour compiler la bibliothèque elle-même et ce qui est nécessaire pour compiler avec la bibliothèque).
La configuration de compilation existe toujours, mais ne doit pas être utilisée car elle n'offre pas les garanties fournies par les configurations api
et implementation
.
Remarque: si vous utilisez uniquement une bibliothèque dans votre module d'application - le cas commun - vous ne remarquerez aucune différence.
vous ne verrez la différence que si vous avez un projet complexe avec des modules qui dépendent les uns des autres ou si vous créez une bibliothèque.
implementation
cacher la dépendance. Ma question a-t-elle un sens?implementation
uniquement x api sera exposé, mais si vous utilisezapi
y, z sera également exposé.Cette réponse démontrera la différence entre
implementation
,api
etcompile
sur un projet.Disons que j'ai un projet avec trois modules Gradle:
app
amyandroidlibrary
comme dépendances.myandroidlibrary
amyjavalibrary
comme dépendances.myjavalibrary
a uneMySecret
classemyandroidlibrary
a uneMyAndroidComponent
classe qui manipule la valeur de laMySecret
classe.Enfin,
app
ne s'intéresse qu'à la valeur demyandroidlibrary
Parlons maintenant des dépendances ...
app
besoin de consommer:myandroidlibrary
, donc dansapp
build.gradle useimplementation
.( Remarque : Vous pouvez également utiliser api / compile. Mais maintenez cette pensée pendant un moment.)
À quoi
myandroidlibrary
devrait ressembler build.gradle? Quelle portée utiliser?Nous avons trois options:
Compiler ou Api (option # 2 ou # 3)
Si vous utilisez
compile
ouapi
. Notre application Android peut désormais accéder à lamyandroidcomponent
dépendance, qui est uneMySecret
classe.Mise en œuvre (option # 1)
Si vous utilisez la
implementation
configuration,MySecret
n'est pas exposé.Alors, quelle configuration choisir? Cela dépend vraiment de vos besoins.
Si vous souhaitez exposer les dépendances, utilisez
api
oucompile
.Si vous ne souhaitez pas exposer les dépendances (masquer votre module interne), utilisez
implementation
.Remarque:
Ceci n'est qu'un aperçu des configurations Gradle, reportez-vous au tableau 49.1. Plugin Java Library - configurations utilisées pour déclarer les dépendances pour une explication plus détaillée.
L'exemple de projet pour cette réponse est disponible sur https://github.com/aldoKelvianto/ImplementationVsCompile
la source
compile
ne garantit pas les mêmes choses que lesapi
garanties.Compile
la configuration est obsolète et doit être remplacée parimplementation
ouapi
.Vous pouvez lire les documents sur https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation .
La brève partie étant-
Pour plus d'explications, reportez-vous à cette image.
la source
Brève solution:
La meilleure approche consiste à remplacer toutes les
compile
dépendances par desimplementation
dépendances. Et seulement lorsque vous perdez l'interface d'un module, vous devez utiliserapi
. Cela devrait entraîner beaucoup moins de recompilation.Explique plus:
Avant le plugin Android Gradle 3.0 : nous avons eu un gros problème qui est qu'un changement de code entraîne la recompilation de tous les modules. La cause principale de ceci est que Gradle ne sait pas si vous fuyez l'interface d'un module à travers un autre ou non.
Après le plug-in Android Gradle 3.0 : le dernier plug-in Android Gradle vous oblige désormais à définir explicitement si vous perdez l'interface d'un module. Sur cette base, il peut faire le bon choix sur ce qu'il doit recompiler.
En tant que telle, la
compile
dépendance a été dépréciée et remplacée par deux nouvelles:api
: vous fuyez l'interface de ce module via votre propre interface, ce qui signifie exactement la même chose que l'anciennecompile
dépendanceimplementation
: vous n'utilisez ce module qu'en interne et ne le faites pas passer par votre interfaceAlors maintenant, vous pouvez explicitement dire à Gradle de recompiler un module si l'interface d'un module utilisé change ou non.
Avec l'aimable autorisation du blog Jeroen Mols
la source
la source
implementation
suivi par unruntime
.La brève différence dans le terme de profane est:
lisez la réponse de @aldok pour un exemple complet.
la source
Depuis la version 5.6.3, la documentation Gradle fournit des règles de base simples pour identifier si une ancienne
compile
dépendance (ou une nouvelle) doit être remplacée par uneimplementation
ou uneapi
dépendance:la source
Gradle 3.0
introduit les changements suivants:compile
->api
api
mot-clé est le même que obsolètecompile
compile
->implementation
Est préférable , car présente certains avantages.
implementation
exposer la dépendance uniquement pour un niveau au moment de la génération (la dépendance est disponible au moment de l'exécution). En conséquence, vous avez une construction plus rapide (pas besoin de recompiler les consommateurs qui sont supérieurs à 1 niveau)provided
->compileOnly
Cette dépendance est disponible uniquement au moment de la compilation (la dépendance n'est pas disponible au moment de l'exécution). Cette dépendance ne peut pas être transitive et l'être
.aar
. Il peut être utilisé avec un processeur d'annotation de temps de compilation et vous permet de réduire un fichier de sortie finalcompile
->annotationProcessor
Très similaire
compileOnly
mais garantit également que la dépendance transitive n'est pas visible pour le consommateurapk
->runtimeOnly
La dépendance n'est pas disponible au moment de la compilation mais disponible au moment de l'exécution.
la source
api = public
,implementation = internal
etcompileOnly = private
- je dois créer ces alias pour ces fonctions car ils sont super confusion.