Debug degli errori di risoluzione delle dipendenze

Quando aggiungi una dipendenza, potresti riscontrare problemi con le dipendenze richieste dalla dipendenza originale e sono in conflitto tra le diverse versioni delle dipendenze. Ecco come analizzare il grafico delle dipendenze e risolvere i problemi più comuni.

Per indicazioni su come correggere gli errori di risoluzione delle dipendenze che riguardano una build personalizzata della logica, consulta Strategie personalizzate per la risoluzione delle dipendenze.

Visualizza le dipendenze del modulo

Alcune dipendenze dirette possono avere dipendenze proprie. Questi vengono chiamati dipendenze transitive. Anziché dover dichiarare manualmente ogni una dipendenza transitiva, Gradle le raccoglie e le aggiunge automaticamente per te. Il plug-in Android per Gradle fornisce un'attività che mostra un elenco le dipendenze vengono risolte da Gradle per un determinato modulo.

Per ogni modulo, il report raggruppa anche le dipendenze in base alla variante di build, al set di origini di test classpath. Di seguito è riportato un report di esempio per il runtime di un modulo dell'app classpath della variante build di debug e compilare classpath dello strumento insieme di origini di test.

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à, procedi come segue:

  1. Seleziona Visualizza > Finestre degli strumenti > Gradle (o fare clic su Gradle nella barra delle finestre degli strumenti).
  2. Espandi AppName > Attività > Android e Fai doppio clic su androidDependencies. Dopo l'esecuzione di Gradle l'attività, si dovrebbe aprire la finestra Esegui per visualizzare l'output.

Per saperne di più sulla gestione delle dipendenze in Gradle, vedi Nozioni di base sulla gestione delle dipendenze nella guida dell'utente di Gradle.

Escludi le dipendenze transitive

Man mano che un'app cresce, può contenere varie dipendenze, tra cui le dipendenze dirette e transitive (librerie di cui l'app da cui dipendono le librerie importate). Per escludere le dipendenze transitive che non ti servono più, puoi utilizzare il metodo exclude parola chiave come indicato di seguito:

Kotlin

dependencies {
    implementation("some-library") {
        exclude(group = "com.example.imgtools", module = "native")
    }
}

Alla moda

dependencies {
    implementation('some-library') {
        exclude group: 'com.example.imgtools', module: 'native'
    }
}

Escludi le dipendenze transitive dalle configurazioni di test

Se devi escludere determinate dipendenze transitive dai test, l'esempio di codice mostrato sopra potrebbe non funzionare come previsto. Questo perché un test configurazione (ad es. androidTestImplementation) estende l'aspetto del modulo Configurazione di implementation. Questo significa che contiene sempre implementation quando Gradle risolve la configurazione.

Quindi, per escludere le dipendenze transitive dai test, devi farlo in come mostrato di seguito:

Kotlin

android.testVariants.all {
    compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
    runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp")
}

Alla moda

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 usare la parola chiave exclude nel blocco delle dipendenze, come mostrato nell'esempio di codice originale Escludi le dipendenze transitive per omettere le dipendenze transitive specifiche del test configurazione e non sono incluse in altre configurazioni.

Correggere gli errori di risoluzione delle dipendenze

Quando aggiungi più dipendenze al progetto dell'app, queste indirizzano le dipendenze transitive potrebbero entrare in conflitto tra loro. Android Gradle il plug-in cerca di risolvere questi conflitti, ma alcuni potrebbero per la compilazione o gli errori di runtime.

Per aiutarti a capire quali dipendenze contribuiscono agli errori, esaminare l'albero delle dipendenze dell'app e cercare che appaiono più di una volta o con versioni in conflitto.

Se non riesci a identificare facilmente la dipendenza duplicata, prova a usare Android UI di Studio per cercare le dipendenze che includono la classe duplicata come segue:

  1. Seleziona Naviga > Classe dalla barra dei menu.
  2. Nella finestra di dialogo di ricerca popup, assicurati che la casella accanto a L'opzione Includi elementi non del progetto è selezionata.
  3. Digita il nome della classe che viene visualizzata nell'errore di generazione.
  4. Controlla i risultati per individuare le dipendenze che includono la classe.

Le seguenti sezioni descrivono i diversi tipi di risoluzione delle dipendenze che potresti riscontrare e come correggerli.

Correggere gli errori duplicati nei corsi

Se una classe appare più di una volta nel classpath del runtime, viene visualizzato simile al seguente:

Program type already present com.example.MyClass

In genere questo errore si verifica a causa di una delle seguenti circostanze:

  • Una dipendenza binaria include una libreria che la tua app include anche come una dipendenza diretta. Ad esempio, la tua app dichiara una dipendenza diretta La Libreria A e la Libreria B, ma la Libreria A include già la Libreria B nella sua binario.
    • Per risolvere il problema, rimuovi la Libreria B come dipendenza diretta.
  • La tua app ha una dipendenza binaria locale e una dipendenza binaria remota nella stessa libreria.
    • Per risolvere il problema, rimuovi una delle dipendenze binarie.

Risolvere i conflitti tra i classpath

Quando Gradle risolve il classpath di compilazione, risolve prima il runtime classpath e utilizza il risultato per determinare quali versioni delle dipendenze verrà aggiunto al classpath di compilazione. In altre parole, il runtime classpath determina i numeri di versione richiesti per dipendenze identiche su a downstream.

Il classpath del runtime della tua app determina anche i numeri di versione utilizzati da Gradle richiede la corrispondenza delle dipendenze nel classpath del runtime per il test dell'app . La gerarchia dei percorsi delle classi è descritta nella Figura 1.

Figura 1. Numeri di versioni delle dipendenze che appaiono in più classpath devono corrispondere in base a questo nella gerarchia.

Un conflitto in cui versioni diverse della stessa dipendenza potrebbero verificarsi più classpath quando, ad esempio, la tua app include una versione una dipendenza utilizzando l'implementation configurazione delle dipendenze e un modulo della libreria include una versione diversa della dipendenza utilizzando Configurazione di runtimeOnly.

Quando risolvi le dipendenze dal runtime e dal tempo di compilazione dei percorsi di classe, Android Il plug-in Gradle 3.3.0 e versioni successive tenta di correggere automaticamente determinati downstream conflitti di versione. Ad esempio, se il classpath del runtime include la Libreria A versione 2.0 e il classpath di compilazione include la Libreria A versione 1.0, il plug-in aggiorna automaticamente la dipendenza dal classpath di compilazione nella libreria A versione 2.0 per evitare errori.

Tuttavia, se il classpath del runtime include la libreria A versione 1.0 e il comando classpath include la libreria A versione 2.0, il plug-in non esegue il downgrade alla libreria A versione 1.0, e si ottiene comunque 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, procedi in uno dei seguenti modi:

  • Includi la versione desiderata della dipendenza come dipendenza api dal tuo . In altre parole, solo il modulo della libreria dichiara la dipendenza, anche il modulo dell'app avrà accesso alla relativa API, in modo transitivo.
  • In alternativa, puoi dichiarare la dipendenza in entrambi i moduli, ma devi assicurati che ogni modulo utilizzi la stessa versione della dipendenza. Prendi in considerazione configurare le proprietà a livello di progetto per garantire che le versioni di ogni dipendenza rimangano coerenti in tutto il progetto.