1291 votes

Quelle est la différence entre la mise en œuvre et la compilation dans Gradle?

Après la mise à jour vers Android Studio 3.0 et la création d'un nouveau projet, j'ai remarqué que, dans build.gradle il existe un nouveau moyen d'ajouter de nouvelles dépendances au lieu de compile il y a implementation et au lieu de testCompile il y a testImplementation .

Exemple:

  implementation 'com.android.support:appcompat-v7:25.0.0'
 testImplementation 'junit:junit:4.12'
 

au lieu de

  compile 'com.android.support:appcompat-v7:25.0.0'
 testCompile 'junit:junit:4.12'
 

Quelle est la différence entre eux et que devrais-je utiliser?

1530voto

humazed Points 398

tl;dr

Il suffit de remplacer:

  • 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é dans la version 3.0 pour remplacer fourni et compile pas. (provided introduite lors de Gradle ne pas avoir un nom de configuration pour que les cas d'utilisation et l'a nommé après Maven disposition de l'étendue).

C'est l'une des dernières modifications à venir avec Gradle 3.0 que Google a annoncé à IO17.

L' compile configuration est maintenant obsolète et doit être remplacé par implementation ou api

À partir de la Gradle de la documentation:

dependencies {
    api 'commons-httpclient:commons-httpclient:3.1'
    implementation 'org.apache.commons:commons-lang3:3.5'
}

Dépendances figurant dans l' api configurations seront transitivement exposés aux consommateurs de la bibliothèque, et en tant que tel ne apparaissent sur la compilation de chemin de classe de consommateurs.

Dépendances trouvé dans l' implementation configuration, sur la d'autre part, de ne pas être exposés aux consommateurs, et donc pas de fuite en les consommateurs compiler classpath. Cela a plusieurs avantages:

  • dépendances ne fuit pas dans la compilation de chemin de classe de consommateurs de plus, afin que vous ne serez jamais accidentellement dépendent transitive la dépendance
  • une compilation plus rapide grâce à la réduction des classpath taille
  • moins recompilations lors de la mise en œuvre des dépendances de changement: les consommateurs n'auraient pas besoin d'être recompilé
  • nettoyeur de publication: lorsqu'il est utilisé en conjonction avec le nouveau maven-publier plugin, bibliothèques Java produire POM fichiers distinguer exactement entre ce qui est requis pour la compilation contre le de la bibliothèque et de ce qui est requis pour l'utilisation de la bibliothèque au moment de l'exécution (en d'autres les mots, ne pas mélanger ce qui est nécessaire pour compiler la bibliothèque elle-même et ce qu' est nécessaire pour compiler la bibliothèque).

La compilation de configuration existe toujours, mais ne devrait pas être utilisé, car il n'offre pas les garanties que l' api et implementation configurations de fournir.


Remarque: si vous êtes seulement en utilisant une bibliothèque dans votre application module-le cas le plus courant - vous ne remarquerez aucune différence.
vous ne verrez la différence, si vous avez un projet complexe avec des modules en fonction les uns des autres, ou si vous créez une bibliothèque.

521voto

aldok Points 4348

Cette réponse sera de démontrer la différence entre implementation, api, et compile sur un projet.


Disons que j'ai un projet avec trois Gradle modules:

  • app (une application Android)
  • myandroidlibrary (Android bibliothèque)
  • myjavalibrary (une bibliothèque Java)

app a myandroidlibrary comme des dépendances. myandroidlibrary a myjavalibrary comme des dépendances.

Dependency1

myjavalibrary a MySecret classe

public class MySecret {

    public static String getSecret() {
        return "Money";
    }
}

myandroidlibrary a MyAndroidComponent classe permettant de manipuler la valeur de MySecret classe.

public class MyAndroidComponent {

    private static String component = MySecret.getSecret();

    public static String getComponent() {
        return "My component: " + component;
    }    
}

Enfin, app ne s'intéresse qu'à la valeur de myandroidlibrary

TextView tvHelloWorld = findViewById(R.id.tv_hello_world);
tvHelloWorld.setText(MyAndroidComponent.getComponent());

Maintenant, nous allons parler des dépendances...

app besoin de consommer :myandroidlibrary, donc, en app construire.gradle utiliser implementation.

(Remarque: Vous pouvez utiliser l'api/compiler trop. Mais attends un peu pour un moment).

dependencies {
    implementation project(':myandroidlibrary')      
}

Dependency2

Que pensez-vous myandroidlibrary construire.gradle devrait ressembler? Dont la portée nous devrions utiliser?

Nous avons trois options:

dependencies {
    // Option #1
    implementation project(':myjavalibrary') 
    // Option #2
    compile project(':myjavalibrary')      
    // Option #3
    api project(':myjavalibrary')           
}

Dependency3

Quelle est la différence entre eux et que dois-je utiliser?

La compilation ou de l'Api (option #2 ou #3) Dependency4

Si vous utilisez compile ou api. Notre Application Android maintenant en mesure d'accéder myandroidcomponent de dépendance, qui est un MySecret classe.

TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can access MySecret
textView.setText(MySecret.getSecret());

La mise en œuvre (option #1)

Dependency5

Si vous utilisez implementation configuration, MySecret n'est pas exposé.

TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can NOT access MySecret
textView.setText(MySecret.getSecret()); // Won't even compile

Ainsi, la configuration, vous devez choisir? Cela dépend vraiment de vos besoins.

Si vous souhaitez exposer dépendances utiliser api ou compile.

Si vous ne voulez pas exposer les dépendances (en cachant votre module interne) puis utiliser implementation.

Note:

Ceci est juste un résumé de Gradle configurations, reportez-vous à la Table 49.1. Bibliothèque Java plugin - configurations utilisées pour déclarer les dépendances pour des explications plus détaillées.

L'exemple de projet pour répondre à cette question est disponible sur https://github.com/aldoKelvianto/ImplementationVsCompile

83voto

Rishav Points 1731

Compile configuration est obsolète et doit être remplacé par implementation ou api.

Vous pouvez lire la documentation à https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation.

La brève partie de l'être-

La principale différence entre le standard plug-in Java et Java Bibliothèque de plugin, c'est que ce dernier introduit le concept d'une API exposés aux consommateurs. Une bibliothèque est un composant Java destiné à être consommées par d'autres composants. Il est d'un usage très courant en cas multi-projet construit, mais aussi dès que vous avez externes les dépendances.

Le plugin expose deux configurations qui peuvent être utilisés pour déclarer dépendances: api et la mise en œuvre. L'api de configuration doit être utilisé pour déclarer les dépendances qui sont exportées par la bibliothèque de l'API, alors que la mise en œuvre de configuration doit être utilisé pour déclarer les dépendances qui sont internes au composant.

Pour plus d'explications, reportez-vous à cette image. Brief explanation

50voto

SHi ON Points 1621

Bref La Solution:

La meilleure approche consiste à remplacer tous les compile dépendances avec implementation dépendances. Et seulement lorsque vous avez une fuite d'un module d'interface, vous devez utiliser api. Que doit causer beaucoup moins de recompilation.

 dependencies {
         implementation fileTree(dir: 'libs', include: ['*.jar'])

         implementation 'com.android.support:appcompat-v7:25.4.0'
         implementation 'com.android.support.constraint:constraint-layout:1.0.2'
         // …

         testImplementation 'junit:junit:4.12'
         androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
             exclude group: 'com.android.support', module: 'support-annotations'
         })
 }

Expliquer Plus En Détail:

Avant Android plugin Gradle 3.0: nous avons eu un gros problème qui est un changement de code provoque tous les modules être recompilés. La cause principale est que Gradle ne sais pas si vous avez fuite de l'interface d'un module à un autre, ou pas.

Après Android plugin Gradle 3.0: le dernier Android plugin Gradle vous demande désormais de définir de manière explicite si vous avez une fuite d'un module d'interface. Basé sur qui il peut faire le bon choix sur ce qu'il doit recompiler.

En tant que tel l' compile de la dépendance a été supprimée et remplacée par deux nouvelles:

  • api:- vous à la fuite de l'interface de ce module par le biais de votre propre interface, ce qui signifie exactement la même chose que le vieux - compile de dépendance

  • implementation: vous n'utiliser ce module en interne et n'a pas de fuite à travers votre interface

Alors maintenant, vous pouvez indiquer explicitement Gradle pour recompiler un module si l'interface d'un module de changements ou pas.

Courtoisie de Jeroen Mols blog

13voto

Rushabh Agarwal Points 91

La brève différence dans laïc du terme est le suivant:

  • Si vous travaillez sur une interface ou d'un module qui fournit un soutien à d'autres modules, en exposant les membres de la dépendance que vous devriez être en utilisant "api".
  • Si vous faites une demande ou d'un module qui va mettre en œuvre ou de l'utilisation de l'énoncé de la dépendance à l'interne, utilisez l'option "mise en œuvre".
  • 'compiler' travaillé même comme "api", cependant, si vous êtes seulement la mise en œuvre ou de l'utilisation de la bibliothèque, "mise en œuvre" fonctionnera mieux et vous faire économiser des ressources.

lire la réponse de @aldok pour un exemple complet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X