Interdipendenze tra strumenti e librerie

Le dipendenze build sono componenti esterni necessari per creare correttamente il progetto. Una build può dipendere da librerie, plug-in, sottoprogetti, SDK Android, strumenti come Kotlin e Java, ambienti di sviluppo come Android Studio e lo stesso Gradle.

Ogni dipendenza può richiedere a sua volta altre dipendenze. Queste sono dette dipendenze transitive e possono aumentare rapidamente le dipendenze complessive utilizzate dalla tua applicazione. Quando vuoi eseguire l'upgrade di una dipendenza, che si tratti di una libreria, di uno strumento o dell'SDK Android, l'upgrade può essere in cascata, eseguendo l'upgrade di molte altre dipendenze.

Spesso, questo non causa problemi, poiché molte librerie seguono uno schema noto come Semantic Versioning. Queste librerie limitano i tipi di modifiche apportate per garantire la compatibilità con le versioni precedenti.

Il controllo delle versioni semantiche segue un formato major.minor.patch. Ad esempio, nel numero di versione 4.8.3, 4 è la versione major, 8 è la versione minor e 3 è il numero patch. Quando la parte major cambia, la libreria potrebbe avere modifiche sostanziali nell'API o nel comportamento. Ciò può influire sul comportamento della build o dell'applicazione.

Quando le parti minor (nuove funzionalità) o patch (correzioni di bug) cambiano, gli sviluppatori della libreria ti comunicano che la libreria è ancora compatibile e non dovrebbe influire sulla tua applicazione.

È importante prestare attenzione a queste modifiche e diversi strumenti di upgrade delle dipendenze possono essere d'aiuto.

Relazioni nella build

Le build Android contengono relazioni tra:

  • Codice sorgente: il codice e le risorse su cui hai il controllo
  • Dipendenze libreria: librerie o moduli esterni che il progetto e i sottoprogetti includono durante la creazione
  • Strumenti: compilatori, plug-in e SDK che traducono il tuo codice sorgente in un'applicazione o una libreria
Crea le dipendenze e le relative relazioni
Figura 1. Instaurare relazioni

Codice sorgente

Il tuo codice sorgente è codice Kotlin o Java che scrivi nella tua applicazione o libreria. Per maggiori dettagli sull'utilizzo di C++, vedi Android NDK.

Il codice sorgente dipende dalle librerie (incluse le librerie di runtime Kotlin e Java) e dall'SDK Android e richiede il compilatore Kotlin o Java corrispondente.

Alcuni codici sorgente includono annotazioni che richiedono un'elaborazione aggiuntiva. Ad esempio, se stai scrivendo codice per Jetpack Compose, puoi aggiungere annotazioni, come @Composable, che devono essere elaborate dal plug-in del compilatore Kotlin. Altre annotazioni possono essere elaborate da un Kotlin Symbol Processor (KSP) o da strumenti di elaborazione delle annotazioni separati.

Dipendenze libreria

Le librerie contengono il bytecode inserito come parte dell'applicazione. Potrebbe essere un JAR Java, una libreria Android (AAR) o un sottoprogetto nella tua build. Molte librerie adottano il versionamento semantico, che può aiutarti a capire se rimangono compatibili (o meno) durante l'upgrade.

Le librerie possono dipendere da altre librerie per il riutilizzo, indicata come dipendenza transitiva. Questo riduce le dipendenze che devi gestire esplicitamente: tu specifichi le dipendenze che usi direttamente e Gradle le inserisce insieme alle dipendenze transitive. Tieni presente che, quando esegui l'upgrade delle dipendenze dirette, queste potrebbero eseguire l'upgrade di queste dipendenze transitive.

A volte una libreria potrebbe richiedere versioni minime dell'SDK Android in fase di runtime (minSdk) o di compilazione (compileSdk). Questo è necessario quando una libreria utilizza le funzioni incluse nell'SDK Android o nelle sue API JDK fornite. Il valore minSdk effettivo della tua applicazione è il valore minSdk più alto richiesto dalla tua applicazione e da tutte le sue dipendenze di librerie dirette e traslative.

L'utilizzo di alcune librerie potrebbe richiedere l'uso di un plug-in Gradle specifico. Questi plug-in di supporto spesso installano Kotlin Symbol Processors o altri processori di annotazioni che generano codice o modificano la compilazione del codice sorgente per supportare l'utilizzo delle funzionalità della libreria. Ad esempio, Jetpack Room include annotazioni e un KSP che li trasforma in codice generato per recuperare e modificare i dati in un database. Jetpack Compose richiede il plug-in del compilatore Compose per modificare le funzioni annotate per gestire come e quando viene eseguita di nuovo la funzione.

Strumenti

Gradle

Gradle è lo strumento di compilazione che legge i file di compilazione e genera l'applicazione o la libreria, oltre a esporre un'API per i plug-in per estenderne le funzionalità. Gradle esegue diversi processi su una o più macchine virtuali Java e i suoi plug-in Java chiamano gli strumenti Java all'interno del JDK.

Plug-in Gradle

I plug-in Gradle estendono Gradle definendo nuove attività e configurazioni. L'applicazione di un plug-in alla build attiva funzionalità specifiche della build, configurate come dati negli script di build. Per le build Android, il plug-in Gradle più importante è il plug-in Android per Gradle (AGP).

Compilatori

Il compilatore Kotlin o Java trasforma il tuo codice sorgente in bytecode eseguibile. Il compilatore Kotlin espone un'API plug-in che consente di eseguire l'analisi esterna e la generazione del codice direttamente all'interno del compilatore, accedendo alla struttura del codice analizzata.

Plug-in per il compilatore

I plug-in del compilatore eseguono l'analisi e la generazione del codice all'interno del compilatore Kotlin mentre quest'ultimo analizza il tuo codice e vengono installati quando applichi i plug-in Gradle alla build.

SDK Android

L'SDK Android contiene la piattaforma Android e le API Java per una versione specifica di Android, nonché gli strumenti corrispondenti. Questi strumenti ti aiutano a gestire l'SDK, a creare le tue applicazioni e a comunicare ed emulare i dispositivi Android.

Ogni versione dell'SDK Android fornisce API Java specifiche a cui può accedere il codice sorgente e il supporto per il desugaring per utilizzare queste API su versioni precedenti di Android.

JDK

Il Java Development Kit, contenente librerie ed eseguibili Java per compilare il codice sorgente Java ed eseguire applicazioni Java. Ci sono diversi JDK in gioco in una build Android. Per ulteriori dettagli, consulta la sezione Versioni Java nelle build Android.

Ambiti Gradle

Gradle raggruppa le dipendenze della libreria in ambiti diversi (chiamati configurazioni nell'API Gradle), il che consente di specificare diversi set di dipendenze di libreria da utilizzare in parti diverse della build. Ad esempio, probabilmente non vorrai includere librerie di test come JUnit nella tua applicazione o libreria pubblicata, ma preferisci che vengano create quando crei ed esegui i test delle unità. Utilizzi gli ambiti anche per aggiungere elaboratori di simboli o di annotazione per analizzare il codice.

Ad esempio, AGP definisce gli ambiti implementation e api, il tuo modo per specificare se una dipendenza deve essere esposta agli utenti del tuo sottoprogetto. Consulta Configurare le dipendenze per le descrizioni di questi e di altri ambiti utilizzati in una build Android.

Aggiungi le dipendenze delle librerie nel blocco dependencies dei file di build come stringhe group:artifact:version:

Kotlin

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation("com.example:library1:1.2.3")
    api("com.example:library2:1.1.1")
}

Alla moda

// In a module-level build script
// explicit dependency strings ("group:artifact:version")
dependencies {
    implementation 'com.example:library1:1.2.3'
    api 'com.example:library2:1.1.1'
}

o in un Catalogo delle versioni:

# Version catalog - gradle/libs.versions.toml
[versions]
exampleLib = "1.2.3"
examplePlugin = "2.3.4"

[libraries]
example-library = { group = "com.example", name = "library", version.ref = "exampleLib" }

[plugins]
example-plugin = { id = "com.example.plugin", version.ref = "examplePlugin" }

e specifica le variabili generate nei file di build:

Kotlin

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation(libs.example.library)
}

Groovy

// In a module-level build script
// Using a version catalog
plugins {
    alias(libs.plugins.example.plugin)
}

dependencies {
    implementation libs.example.library
}