Quando aggiungi una dipendenza, potresti riscontrare problemi con le dipendenze richieste dalla dipendenza originale e conflitti tra le diverse versioni delle dipendenze. Ecco come analizzare il grafico delle dipendenze e risolvere i problemi comuni che si verificano.
Per indicazioni sulla risoluzione degli errori di risoluzione delle dipendenze che prevedono una logica di build personalizzata, consulta Strategie di risoluzione delle dipendenze personalizzate.
Visualizza le dipendenze del modulo
Alcune dipendenze dirette possono avere dipendenze proprie. Queste sono chiamate dipendenze transitive. Anziché dover dichiarare manualmente ogni dipendenza transitiva, Gradle le raccoglie e le aggiunge automaticamente. Il plug-in Android per Gradle fornisce un'attività che mostra un elenco delle dipendenze risolte da Gradle per un determinato modulo.
Per ogni modulo, il report raggruppa anche le dipendenze in base alla variante della build, al set di origini di test e al percorso della classe. Di seguito è riportato un report di esempio per il classpath di runtime di un modulo dell'app della variante della build di debug e il classpath di compilazione del set di origine del test instrumentato.
debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...
debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...
Per eseguire l'attività:
- Seleziona Visualizza > Finestre degli strumenti > Gradle (o fai clic su Gradle nella barra delle finestre degli strumenti).
- Espandi AppName > Tasks > android e fai doppio clic su androidDependencies. Dopo che Gradle ha eseguito l'attività, dovrebbe aprirsi la finestra Esegui per visualizzare l'output.
Per ulteriori informazioni sulla gestione delle dipendenze in Gradle, consulta Nozioni di base sulla gestione delle dipendenze nella guida dell'utente di Gradle.
Escludi le dipendenze transitive
Man mano che l'ambito di un'app diventa più ampio, può contenere una serie di dipendenze, tra cui quelle dirette e transitive (librerie da cui dipendono le librerie importate dalla tua app).
Per escludere le dipendenze transitive di cui non hai più bisogno, puoi utilizzare la parola chiave exclude
come indicato di seguito:
Kotlin
dependencies { implementation("some-library") { exclude(group = "com.example.imgtools", module = "native") } }
trendy
dependencies { implementation('some-library') { exclude group: 'com.example.imgtools', module: 'native' } }
Escludi le dipendenze transitive dalle configurazioni di test
Se devi escludere dai test determinate dipendenze transitive,
l'esempio di codice mostrato sopra potrebbe non funzionare come previsto. È perché una configurazione
di test (ad es. androidTestImplementation
) estende la configurazione
implementation
del modulo. In altre parole, contiene sempre le dipendenze implementation
quando Gradle risolve la configurazione.
Quindi, per escludere le dipendenze transitive dai tuoi test, devi farlo al momento dell'esecuzione, come illustrato di seguito:
Kotlin
android.testVariants.all { compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") }
trendy
android.testVariants.all { variant -> variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' }
Nota: puoi comunque utilizzare la parola chiave exclude
nel blocco delle dipendenze come mostrato nell'esempio di codice originale della sezione Escludi dipendenze transitive per omettere le dipendenze transitive specifiche per la configurazione di test e che non sono incluse in altre configurazioni.
Correggi gli errori di risoluzione delle dipendenze
Quando aggiungi più dipendenze al progetto dell'app, queste ultime potrebbero entrare in conflitto tra loro. Il plug-in Android Gradle cerca di risolvere questi conflitti in modo agevole, ma alcuni conflitti potrebbero causare errori in fase di compilazione o di runtime.
Per aiutarti a capire quali dipendenze contribuiscono agli errori, controlla la struttura delle dipendenze dell'app e cerca eventuali dipendenze che appaiono più di una volta o con versioni in conflitto.
Se non riesci a identificare facilmente la dipendenza duplicata, prova a usare l'interfaccia utente di Android Studio per cercare le dipendenze che includono la classe duplicata, come indicato di seguito:
- Seleziona Naviga > Corso dalla barra dei menu.
- Nella finestra di dialogo di ricerca popup, assicurati che la casella accanto a Includi elementi non appartenenti al progetto sia selezionata.
- Digita il nome della classe visualizzato nell'errore di generazione.
- Ispeziona i risultati per verificare le dipendenze che includono la classe.
Le seguenti sezioni descrivono i diversi tipi di errori di risoluzione delle dipendenze che potresti riscontrare e come risolverli.
Correggere gli errori duplicati dei corsi
Se una classe compare più di una volta sul classpath di runtime, viene visualizzato un errore simile al seguente:
Program type already present com.example.MyClass
Generalmente questo errore si verifica a causa di una delle seguenti circostanze:
- Una dipendenza binaria include una libreria che la tua app include anche come dipendenza diretta. Ad esempio, la tua app dichiara una dipendenza diretta dalla libreria A e dalla libreria B, ma la Libreria A include già la Libreria B nel suo file binario.
- Per risolvere questo problema, rimuovi la Libreria B come dipendenza diretta.
- La tua app ha una dipendenza binaria locale e una dipendenza binaria remota sulla stessa libreria.
- Per risolvere questo problema, rimuovi una delle dipendenze binarie.
Risolvere i conflitti tra i percorsi delle classi
Una volta che Gradle risolve classpath di compile, prima risolve il classpath runtime e utilizza il risultato per determinare quali versioni delle dipendenze aggiungere al classpath di compile. In altre parole, classpath di runtime determina i numeri di versione richiesti per le dipendenze identiche dei classpath downstream.
Il classpath di runtime dell'app determina anche i numeri di versione richiesti da Gradle per la corrispondenza delle dipendenze nel classpath di runtime per l'APK di test dell'app. La gerarchia dei classpath è descritta nella Figura 1.
Potrebbe verificarsi un conflitto in cui diverse versioni della stessa dipendenza appaiono su più percorsi di una classe quando, ad esempio, la tua app include una versione di una dipendenza che utilizza la configurazione delle dipendenze implementation
e un modulo della libreria include una versione diversa della dipendenza utilizzando la configurazione runtimeOnly
.
Quando risolvi le dipendenze dai classpath di runtime e tempo di compilazione, il plug-in Android Gradle 3.3.0 e versioni successive tenta di risolvere automaticamente alcuni conflitti tra le versioni downstream. Ad esempio, se il classpath del runtime include Library A versione 2.0 e il classpath di compile include la Library A versione 1.0, il plug-in aggiorna automaticamente la dipendenza di compile classpath alla Library A versione 2.0 per evitare errori.
Tuttavia, se il classpath del runtime include la Libreria A versione 1.0 e il classpath di compile include la Libreria A versione 2.0, il plug-in non esegue il downgrade della dipendenza del classpath di compile alla Libreria A versione 1.0 e viene comunque visualizzato un errore simile al seguente:
Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'. Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.
Per risolvere il problema, esegui una delle seguenti operazioni:
- Includi la versione desiderata della dipendenza come dipendenza
api
al modulo libreria. In altre parole, solo il modulo libreria dichiara la dipendenza, ma anche il modulo dell'app avrà accesso in modo transitivo alla sua API. - In alternativa, puoi dichiarare la dipendenza in entrambi i moduli, ma assicurati che ogni modulo utilizzi la stessa versione della dipendenza. Valuta la possibilità di configurare proprietà a livello di progetto per garantire che le versioni di ogni dipendenza rimangano coerenti in tutto il progetto.