android download studio - Quelle est la différence entre l'implémentation et la compilation dans Gradle
Cette réponse va démontrer la différence entre l' implementation
, l' api
et la compile
sur un projet. Disons que j'ai un projet avec trois modules Gradle:
- application (une application Android)
- myandroidlibrary (une bibliothèque Android)
- myjavalibrary (une bibliothèque Java)
app
a myandroidlibrary
tant que dépendances. myandroidlibrary
a myjavalibrary
comme dépendances.
application -> myandroidlibrary -> myjavalibrary
myjavalibrary
a une classe MySecret
public class MySecret {
public static String getSecret() {
return "Money";
}
}
myandroidlibrary
a MyAndroidComponent
classe MyAndroidComponent
qui manipule la valeur de la classe MySecret
.
public class MyAndroidComponent {
private static String component = MySecret.getSecret();
public static String getComponent() {
return "My component: " + component;
}
}
Enfin, l' app
ne s'intéresse qu'à la valeur de myandroidlibrary
TextView tvHelloWorld = findViewById(R.id.tv_hello_world);
tvHelloWorld.setText(MyAndroidComponent.getComponent());
Parlons maintenant des dépendances sur l' app
build.gradle. C'est très simple et intuitif.
dependencies {
implementation project(':myandroidlibrary')
}
À quoi pensez-vous que myandroidlibrary
build.gradle devrait ressembler? Nous avons trois options:
dependencies {
// Option #1
implementation project(':myjavalibrary')
// Option #2
compile project(':myjavalibrary')
// Option #3
api project(':myjavalibrary')
}
Quelle est la différence entre eux et que devrais-je utiliser?
Compiler et Api
Si vous utilisez compile
et api
. Notre application Android peut maintenant accéder à la dépendance myandroidcomponent
, qui est une classe MySecret
.
TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can access MySecret
textView.setText(MySecret.getSecret());
la mise en oeuvre
Si vous utilisez la configuration d' implementation
, 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
Alors, quelle configuration choisir? Cela dépend vraiment de vos besoins.
Si vous voulez exposer des dépendances, utilisez api
ou compile
, si vous ne voulez pas exposer les dépendances (masquer votre module interne), alors utilisez l' implementation
.
Ceci est juste un aperçu des configurations de Gradle, se référer au Tableau 49.1. Plugin Java Library - configurations utilisées pour déclarer les dépendances pour une explication plus détaillée.
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 y a une nouvelle façon d'ajouter de nouvelles dépendances au lieu de compile
il y a implementation
et à la place 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?
Brève solution:
La meilleure approche consiste à remplacer toutes les dépendances de compile
dépendances d' implementation
. Et seulement lorsque vous fuyez l'interface d'un module, vous devez utiliser api
. Cela devrait 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'
})
}
Explique plus:
Avant Android Gradle plugin 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 première de ceci est que Gradle ne sait pas si vous fuyez l'interface d'un module par un autre ou non.
Après Android Gradle plugin 3.0 : le dernier plugin Android Gradle vous demande maintenant de définir explicitement si vous perdez l'interface d'un module. Basé sur cela, il peut faire le bon choix sur ce qu'il devrait recompiler.
En tant que tel, la dépendance de compile
a été dépréciée et remplacée par deux nouvelles:
api
: vous perdez l'interface de ce module via votre propre interface, ce qui signifie exactement la même chose que l'ancienne dépendance de lacompile
implementation
: vous utilisez uniquement ce module en interne et ne le fuit pas via votre interface
Donc maintenant vous pouvez dire explicitement à Gradle de recompiler un module si l'interface d'un module utilisé change ou non.
Courtoisie du blog de Jeroen Mols