Plug-in Android per Gradle 4.0.0 (aprile 2020)

Questa versione del plug-in Android richiede quanto segue:

4.0.1 (luglio 2020)

Questo aggiornamento secondario supporta la compatibilità con nuove impostazioni predefinite e funzionalità per la visibilità dei pacchetti in Android 11.

Nelle versioni precedenti di Android, era possibile visualizzare un elenco di tutte le app installate su un dispositivo. A partire da Android 11 (livello API 30), per impostazione predefinita le app hanno accesso solo a un elenco filtrato di pacchetti installati. Per visualizzare un elenco più ampio di app sul sistema, ora devi aggiungere un elemento <queries> nel manifest Android della tua app o della tua libreria.

Il plug-in Android per Gradle 4.1+ è già compatibile con la nuova dichiarazione <queries>; tuttavia, le versioni precedenti non sono compatibili. Se aggiungi l'elemento <queries> o se inizi a utilizzare una libreria o un SDK che supporta il targeting di Android 11, potresti riscontrare errori di unione del manifest durante la creazione dell'app.

Per risolvere questo problema, rilasceremo una serie di patch per AGP 3.3 e versioni successive. Se utilizzi una versione precedente di AGP, esegui l'upgrade a una delle seguenti versioni:

Versione minima Versione predefinita Note
Gradle 6.1.1 6.1.1 Per scoprire di più, consulta la sezione Aggiornare Gradle.
Strumenti di compilazione SDK 29.0.2 29.0.2 Installa o configura gli strumenti di creazione dell'SDK.

Per ulteriori informazioni su questa nuova funzionalità, consulta Visibilità dei pacchetti in Android 11.

Nuove funzionalità

Questa versione del plug-in Android per Gradle include le seguenti nuove funzionalità.

Supporto di Android Studio Build Analyzer

La finestra Build Analyzer ti aiuta a comprendere e diagnosticare i problemi relativi al processo di build, ad esempio ottimizzazioni disattivate e attività configurate in modo errato. Questa funzionalità è disponibile quando utilizzi Android Studio 4.0 e versioni successive con il plug-in Android per Gradle 4.0.0 e versioni successive. Puoi aprire la finestra Build Analyzer da Android Studio nel seguente modo:

  1. Se non l'hai ancora fatto, crea l'app selezionando Build > Make Project dalla barra dei menu.
  2. Seleziona Visualizza > Finestre degli strumenti > Build dalla barra dei menu.
  3. Nella finestra Build, apri la finestra Build Analyzer in uno dei seguenti modi:
    • Una volta completata la creazione del progetto da parte di Android Studio, fai clic sulla scheda Build Analyzer.
    • Una volta completata la creazione del progetto da parte di Android Studio, fai clic sul link sul lato destro della finestra Output build.

La finestra Build Analyzer organizza i possibili problemi di build in una struttura ad albero a sinistra. Puoi esaminare e fare clic su ogni problema per analizzarne i dettagli nel riquadro a destra. Quando Android Studio analizza la build, calcola l'insieme di attività che hanno determinato la durata della build e fornisce una visualizzazione per aiutarti a comprendere l'impatto di ciascuna di queste attività. Puoi anche visualizzare i dettagli sugli avvisi espandendo il nodo Avvisi.

Per saperne di più, leggi Identificare le regressioni della velocità di build.

Rimozione dello zucchero sintattico della libreria Java 8 in D8 e R8

Il plug-in Android Gradle ora include il supporto per l'utilizzo di una serie di API del linguaggio Java 8 senza richiedere un livello API minimo per la tua app.

Tramite un processo chiamato desugaring, il compilatore DEX, D8, in Android Studio 3.0 e versioni successive forniva già un supporto sostanziale per le funzionalità del linguaggio Java 8 (come espressioni lambda, metodi di interfaccia predefiniti, try-with-resources e altro ancora). In Android Studio 4.0, il motore di desugarizzazione è stato esteso per poter eseguire la desugarizzazione delle API del linguaggio Java. Ciò significa che ora puoi includere API linguistiche standard disponibili solo nelle versioni recenti di Android (ad esempio java.util.streams) nelle app che supportano versioni precedenti di Android.

In questa release è supportato il seguente insieme di API:

  • Stream sequenziali (java.util.stream)
  • Un sottoinsieme di java.time
  • java.util.function
  • Aggiunte recenti a java.util.{Map,Collection,Comparator}
  • Opzionali (java.util.Optional, java.util.OptionalInt e java.util.OptionalDouble) e alcune altre nuove classi utili con le API precedenti
  • Alcune aggiunte a java.util.concurrent.atomic (nuovi metodi su AtomicInteger, AtomicLong e AtomicReference)
  • ConcurrentHashMap (con correzioni di bug per Android 5.0)

Per supportare queste API di linguaggio, D8 compila un file DEX di libreria separato che contiene un'implementazione delle API mancanti e lo include nella tua app. Il processo di desugaring riscrive il codice della tua app per utilizzare invece questa libreria in runtime.

Per abilitare il supporto di queste API per le lingue, includi quanto segue nel file build.gradle del modulo dell'app:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4' }

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled = true
  }

compileOptions { // Flag to enable support for the new language APIs isCoreLibraryDesugaringEnabled = true // Sets Java compatibility to Java 8 sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.4") }

Tieni presente che potresti dover includere lo snippet di codice riportato sopra anche nel file build.gradle di un modulo della libreria se

  • I test strumentati del modulo della libreria utilizzano queste API di linguaggio (direttamente o tramite il modulo della libreria o le relative dipendenze). In questo modo, le API mancanti vengono fornite per l'APK di test strumentato.

  • Vuoi eseguire lint sul modulo della libreria in isolamento. Questo per aiutare lint a riconoscere gli utilizzi validi delle API del linguaggio ed evitare di segnalare falsi avvisi.

Nuove opzioni per attivare o disattivare le funzionalità di creazione

Il plug-in Android per Gradle 4.0.0 introduce un nuovo modo per controllare le funzionalità di compilazione che vuoi attivare e disattivare, come View Binding e Data Binding. Quando vengono aggiunte nuove funzionalità, queste vengono disattivate per impostazione predefinita. Puoi quindi utilizzare il blocco buildFeatures per attivare solo le funzionalità che ti interessano e ottimizzare il rendimento della build per il tuo progetto. Puoi impostare le opzioni per ogni modulo nel file build.gradle a livello di modulo nel seguente modo:

android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}
android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}

Puoi anche specificare l'impostazione predefinita per queste funzionalità in tutti i moduli di un progetto includendo uno o più dei seguenti elementi nel file gradle.properties del progetto, come mostrato di seguito. Tieni presente che puoi comunque utilizzare il blocco buildFeatures nel file build.gradle a livello di modulo per eseguire l'override di queste impostazioni predefinite a livello di progetto.

android.defaults.buildfeatures.buildconfig=true
android.defaults.buildfeatures.aidl=true
android.defaults.buildfeatures.renderscript=true
android.defaults.buildfeatures.resvalues=true
android.defaults.buildfeatures.shaders=true

Dipendenze tra funzionalità

Nelle versioni precedenti del plug-in Android per Gradle, tutti i moduli delle funzionalità potevano dipendere solo dal modulo base dell'app. Quando utilizzi il plug-in Android per Gradle 4.0.0, ora puoi includere un modulo delle funzionalità che dipende da un altro modulo delle funzionalità. ovvero una funzionalità :video può dipendere dalla funzionalità :camera, che dipende dal modulo di base, come mostrato nella figura seguente.

Dipendenze tra funzionalità

Il modulo di funzionalità :video dipende dalla funzionalità :camera, che dipende dal modulo di base :app.

Ciò significa che quando la tua app richiede di scaricare un modulo di funzionalità, l'app scarica anche altri moduli di funzionalità da cui dipende. Dopo aver creato moduli delle funzionalità per la tua app, puoi dichiarare una dipendenza tra funzionalità nel file build.gradle del modulo. Ad esempio, il modulo :video dichiara una dipendenza da :camera nel seguente modo:

// In the build.gradle file of the ':video' module.
dependencies {
  // All feature modules must declare a dependency
  // on the base module.
  implementation project(':app')
  // Declares that this module also depends on the 'camera'
  // feature module.
  implementation project(':camera')
  ...
}
// In the build.gradle file of the ':video' module.
dependencies {
    // All feature modules must declare a dependency
    // on the base module.
    implementation(project(":app"))
    // Declares that this module also depends on the 'camera'
    // feature module.
    implementation(project(":camera"))
    ...
}

Inoltre, devi attivare la funzionalità di dipendenza tra funzionalità in Android Studio (per supportare la funzionalità durante la modifica della configurazione di esecuzione, ad esempio) facendo clic su Guida > Modifica opzioni VM personalizzate dalla barra dei menu e includendo quanto segue:

-Drundebug.feature.on.feature=true

Metadati delle dipendenze

Quando crei la tua app utilizzando il plug-in Android per Gradle 4.0.0 e versioni successive, il plug-in include metadati che descrivono le dipendenze compilate nella tua app. Quando carichi l'app, Play Console esamina questi metadati per offrirti i seguenti vantaggi:

  • Ricevi avvisi per problemi noti relativi agli SDK e alle dipendenze utilizzati dalla tua app
  • Ricevere feedback utili per risolvere i problemi

I dati vengono compressi, criptati da una chiave di firma di Google Play e archiviati nel blocco di firma dell'app di rilascio. Tuttavia, puoi ispezionare i metadati nei file di build intermedi locali nella seguente directory: <project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt.

Se preferisci non condividere queste informazioni, puoi disattivarle includendo quanto segue nel file build.gradle del modulo:

android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}
android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}

Importa librerie native dalle dipendenze AAR

Ora puoi importare librerie C/C++ dalle dipendenze AAR della tua app. Quando segui i passaggi di configurazione descritti di seguito, Gradle rende automaticamente disponibili queste librerie native per l'utilizzo con il sistema di build nativo esterno, ad esempio CMake. Tieni presente che Gradle rende disponibili queste librerie solo per la build; devi comunque configurare gli script di build per utilizzarle.

Le librerie vengono esportate utilizzando il formato del pacchetto Prefab.

Ogni dipendenza può esporre al massimo un pacchetto Prefab, che comprende uno o più moduli. Un modulo Prefab è una singola libreria, che può essere una libreria condivisa, statica o solo di intestazione.

In genere, il nome del pacchetto corrisponde al nome dell'artefatto Maven e il nome del modulo corrisponde al nome della libreria, ma non è sempre così. Poiché devi conoscere il nome del pacchetto e del modulo delle librerie, potresti dover consultare la documentazione della dipendenza per determinare quali sono questi nomi.

Configurare il sistema di build nativo esterno

Per visualizzare i passaggi da seguire, segui la procedura riportata di seguito per il sistema di compilazione nativo esterno che intendi utilizzare.

Ciascuna delle dipendenze AAR della tua app che include codice nativo espone un file Android.mk che devi importare nel tuo progetto ndk-build. Importa questo file utilizzando il comando import&endash;module, che cerca i percorsi che specifichi utilizzando la proprietà import&endash;add&endash;path nel progetto ndk-build. Ad esempio, se la tua applicazione definisce libapp.so e utilizza curl, devi includere quanto segue nel file Android.mk:

  1. Per CMake:

    add_library(app SHARED app.cpp)

    # Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

  2. Per ndk-build:

    include $(CLEAR_VARS)
    LOCAL_MODULE := libapp
    LOCAL_SRC_FILES := app.cpp
    # Link libcurl from the curl AAR.
    LOCAL_SHARED_LIBRARIES := curl
    include $(BUILD_SHARED_LIBRARY)

    # If you don't expect that your project will be built using versions of the NDK # older than r21, you can omit this block. ifneq ($(call ndk-major-at-least,21),true) $(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH)) endif

    # Import all modules that are included in the curl AAR. $(call import-module,prefab/curl)

Le dipendenze native incluse in un AAR vengono esposte al tuo progetto CMake tramite la variabile CMAKE_FIND_ROOT_PATH{: .external}. Questo valore verrà impostato automaticamente da Gradle quando viene richiamato CMake, quindi se il tuo sistema di compilazione modifica questa variabile, assicurati di aggiungere anziché assegnarla.

Ogni dipendenza espone un pacchetto config-file{: .external} alla build CMake, che importi con il comando find_package{: .external}. Questo comando cerca i pacchetti config-file che corrispondono al nome e alla versione del pacchetto specificati ed espone i target che definisce per essere utilizzati nella build. Ad esempio, se la tua applicazione definisce libapp.so e utilizza curl, devi includere quanto segue nel file CMakeLists.txt:


add_library(app SHARED app.cpp)

# Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

Ora puoi specificare #include "curl/curl.h" in app.cpp. Quando crei il progetto, il sistema di build nativo esterno esegue automaticamente il collegamento libapp.so a libcurl.so e inserisce libcurl.so nel pacchetto APK o nell'app bundle. Per ulteriori informazioni, consulta l'esempio di prefabbricato curl{:.external}.

Modifiche al comportamento

Quando utilizzi questa versione del plug-in, potresti riscontrare le seguenti modifiche nel comportamento.

Aggiornamenti della configurazione di firma v1/v2

Il comportamento delle configurazioni della firma dell'app nel blocco signingConfig è cambiato come segue:

Firma v1

  • Se v1SigningEnabled è abilitato in modo esplicito, AGP esegue la firma dell'app v1.
  • Se v1SigningEnabled è disattivato esplicitamente dall'utente, la firma dell'app v1 non viene eseguita.
  • Se l'utente non ha attivato esplicitamente la firma v1, questa può essere disattivata automaticamente in base a minSdk e targetSdk.

Firma v2

  • Se v2SigningEnabled è abilitato in modo esplicito, AGP esegue la firma dell'app v2.
  • Se v2SigningEnabled è disattivato esplicitamente dall'utente, la firma v2 dell'app non viene eseguita.
  • Se l'utente non ha attivato esplicitamente la firma v2, questa può essere disattivata automaticamente in base a targetSdk.

Queste modifiche consentono ad AGP di ottimizzare le build disattivando il meccanismo di firma in base al fatto che l'utente abbia attivato o meno questi flag in modo esplicito. Prima di questa release, era possibile disattivare v1Signing anche se era stato attivato in modo esplicito, il che poteva creare confusione.

Plug-in Android per Gradle feature e instantapp rimossi

Il plug-in Android per Gradle 3.6.0 ha ritirato il plug-in delle funzionalità (com.android.feature) e il plug-in delle app istantanee (com.android.instantapp) a favore dell'utilizzo del plug-in delle funzionalità dinamiche (com.android.dynamic-feature) per creare e pacchettizzare le tue app istantanee utilizzando gli Android App Bundle.

Nel plug-in Android per Gradle 4.0.0 e versioni successive, questi plug-in obsoleti sono completamente rimossi. Pertanto, per utilizzare l'ultimo plug-in Android Gradle, devi eseguire la migrazione della tua app istantanea per supportare Android App Bundle. Se esegui la migrazione delle tue app istantanee, puoi sfruttare i vantaggi degli app bundle e semplificare la progettazione modulare della tua app.

Nota: per aprire i progetti che utilizzano i plug-in rimossi in Android Studio 4.0 e versioni successive, il progetto deve utilizzare il plug-in Android per Gradle 3.6.0 o versioni precedenti.

Funzionalità di elaborazione separata delle annotazioni rimossa

La possibilità di separare l'elaborazione delle annotazioni in un'attività dedicata è stata rimossa. Questa opzione veniva utilizzata per mantenere la compilazione Java incrementale quando i processori di annotazioni non incrementali vengono utilizzati in progetti solo Java; veniva attivata impostando android.enableSeparateAnnotationProcessing su true nel file gradle.properties, che non funziona più.

Ti consigliamo invece di eseguire la migrazione all'utilizzo di processori di annotazione incrementale per migliorare il rendimento della build.

includeCompileClasspath è deprecato

Il plug-in Android Gradle non controlla né include più i processori di annotazioni che dichiari nel classpath di compilazione e la proprietà DSL annotationProcessorOptions.includeCompileClasspath non ha più alcun effetto. Se includi i processori di annotazioni nel classpath di compilazione, potresti visualizzare il seguente errore:

Error: Annotation processors must be explicitly declared now.

Per risolvere il problema, devi includere i processori di annotazioni nei tuoi file build.gradle utilizzando la configurazione delle dipendenze annotationProcessor. Per saperne di più, leggi Aggiungere processori di annotazioni.

Pacchettizzazione automatica delle dipendenze precompilate utilizzate da CMake

Le versioni precedenti del plug-in Android Gradle richiedevano di pacchettizzare esplicitamente tutte le librerie precompilate utilizzate dalla build nativa esterna di CMake utilizzando jniLibs. Potresti avere librerie nella directory src/main/jniLibs del tuo modulo o in un'altra directory configurata nel file build.gradle:

sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.srcDirs = ['libs']
  }
}
sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.setSrcDirs(listOf("libs"))
  }
}

Con il plug-in Android per Gradle 4.0, la configurazione precedente non è più necessaria e comporterà un errore di compilazione:

* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
  > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
    > More than one file was found with OS independent path 'lib/x86/libprebuilt.so'

La build nativa esterna ora pacchettizza automaticamente queste librerie, quindi il pacchettizzazione esplicita della libreria con jniLibs genera un duplicato. Per evitare l'errore di build, sposta la libreria precompilata in una posizione esterna a jniLibs o rimuovi la configurazione jniLibs dal file build.gradle.

Problemi noti

Questa sezione descrive i problemi noti esistenti nel plug-in Android per Gradle 4.0.0.

Race condition nel meccanismo di worker Gradle

Le modifiche nel plug-in Android per Gradle 4.0 possono attivare una condizione di competizione in Gradle quando viene eseguito con &endash;&endash;no&endash;daemon e versioni di Gradle 6.3 o precedenti, causando il blocco delle build al termine della compilazione.

Questo problema verrà risolto in Gradle 6.4.