android menu - Qual è la differenza tra l'implementazione e la compilazione in Gradle?




html activity (5)

Dopo l'aggiornamento ad Android Studio 3.0 e la creazione di un nuovo progetto, ho notato che in build.gradle c'è un nuovo modo di aggiungere nuove dipendenze invece di compile c'è implementation e invece di testCompile c'è testImplementation .

Esempio:

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

invece di

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

Qual è la differenza tra loro e cosa dovrei usare?


Answers

La breve differenza nel termine del laico è:

  • Se stai lavorando su un'interfaccia o un modulo che fornisce supporto ad altri moduli esponendo i membri della dipendenza dichiarata, dovresti usare 'API'.
  • Se stai facendo un'applicazione o un modulo che implementerà o utilizzerà internamente la dipendenza dichiarata, usa "implementazione".
  • 'compilare' ha funzionato come 'API', tuttavia, se si sta solo implementando o utilizzando qualsiasi libreria, 'implementazione' funzionerà meglio e ti farà risparmiare risorse.

leggi la risposta di @aldok per un esempio completo.


Compile configurazione era deprecata e dovrebbe essere sostituita dall'implementazione o dalla api .

Puoi leggere i documenti su https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation .

La breve parte è-

La differenza fondamentale tra il plug-in Java standard e il plug-in Java Library è che quest'ultimo introduce il concetto di API esposta ai consumatori. Una libreria è un componente Java pensato per essere utilizzato da altri componenti. È un caso d'uso molto comune nelle build multi-progetto, ma anche quando si hanno dipendenze esterne.

Il plugin espone due configurazioni che possono essere utilizzate per dichiarare dipendenze: api e implementazione. La configurazione di API deve essere utilizzata per dichiarare dipendenze che vengono esportate dall'API della libreria, mentre la configurazione di implementazione deve essere utilizzata per dichiarare dipendenze interne al componente.

Per ulteriori spiegazioni fare riferimento a questa immagine.


Breve soluzione:

L'approccio migliore consiste nel sostituire tutte le dipendenze di compile con le dipendenze di implementation . E solo dove perdi l'interfaccia di un modulo, dovresti usare l' api . Questo dovrebbe causare molto meno ricompilazione.

 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'
         })
 }

Spiega meglio:

Prima di Android Gradle plugin 3.0 : abbiamo avuto un grosso problema che è una modifica del codice causa la ricompilazione di tutti i moduli. La causa principale di questo è che Gradle non sa se si perde l'interfaccia di un modulo attraverso un altro o meno.

Dopo Android Gradle plugin 3.0 : l'ultimo plugin Gradle per Android ora richiede di definire esplicitamente se si perde un'interfaccia di un modulo. In base a ciò, può fare la scelta giusta su ciò che dovrebbe ricompilare.

Come tale, la dipendenza di compile è stata deprecata e sostituita da due nuove:

  • api : si perde l'interfaccia di questo modulo attraverso la propria interfaccia, che significa esattamente la stessa della vecchia dipendenza di compile

  • implementation : si utilizza questo modulo solo internamente e non si diffonde attraverso l'interfaccia

Quindi ora puoi dire esplicitamente a Gradle di ricompilare un modulo se l'interfaccia di un modulo usato cambia o no.

Per gentile concessione del blog di Jeroen Mols


tl; dr

Basta sostituire:

  • compile con l' implementation
  • testCompile con testImplementation
  • debugCompile con debugImplementation
  • androidTestCompile con androidTestImplementation
  • compileOnly è ancora valido. È stato aggiunto in 3.0 per sostituire fornito e non compilato. ( provided introdotto quando Gradle non aveva un nome di configurazione per quel caso d'uso e lo chiamò dopo l'ambito fornito da Maven.)

È uno dei cambiamenti che si verificano con Gradle 3.0 che Google ha annunciato all'IO17 .

La configurazione di compile è ora deprecata e dovrebbe essere sostituita dall'implementazione o dalla api

Dalla documentazione di Gradle :

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

Le dipendenze che appaiono nelle configurazioni api saranno esposte in modo transitorio ai consumatori della libreria e come tali appariranno sul classpath compilato dei consumatori.

Le dipendenze riscontrate nella configurazione implementation , d'altra parte, non saranno esposte ai consumatori e quindi non coleranno nel classpath compilato dei consumatori. Questo ha diversi vantaggi:

  • le dipendenze non colano più nel classpath compilato dei consumatori, quindi non dipenderete mai accidentalmente da una dipendenza transitiva
  • compilazione più veloce grazie alla ridotta dimensione del percorso di classe
  • meno ricompense quando cambiano le dipendenze dell'implementazione: i consumatori non dovrebbero essere ricompilati
  • Pubblicazione più pulita: se utilizzata insieme al nuovo plug-in di pubblicazione di Maven, le librerie Java producono file POM che distinguono esattamente tra ciò che è necessario compilare rispetto alla libreria e ciò che è necessario per utilizzare la libreria in fase di esecuzione (in altre parole, non mescolare ciò che è necessario per compilare la libreria stessa e ciò che è necessario compilare contro la libreria).

La configurazione di compilazione esiste ancora, ma non dovrebbe essere utilizzata in quanto non offre le garanzie fornite api e dalle configurazioni di implementation .

Nota: se si utilizza solo una libreria nel modulo dell'app, nel caso comune, non si noterà alcuna differenza.
vedrai la differenza solo se hai un progetto complesso con moduli che dipendono l'uno dall'altro, oppure stai creando una libreria.


Il problema, come indicato nei tuoi registri, è di 2 dipendenze che cercano di utilizzare versioni diverse della terza dipendenza. Aggiungi uno dei seguenti file all'app-gradle:

androidTestCompile 'com.google.code.findbugs:jsr305:2.0.1'
androidTestCompile 'com.google.code.findbugs:jsr305:1.3.9'




android android-studio gradle build.gradle gradle-plugin