Plug-in Android per Gradle 4.0.0 (aprile 2020)

Questa versione del plug-in Android richiede:

4.0.1 (luglio 2020)

Questo aggiornamento secondario supporta la compatibilità con le nuove impostazioni 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 <queries> elemento nel manifest Android della tua app o libreria.

Il plug-in Android per Gradle 4.1 e versioni successive è già compatibile con la nuova <queries> dichiarazione, ma le versioni precedenti non lo sono compatibile. 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 saperne di più, consulta la sezione Aggiornare Gradle.
Strumenti di build dell'SDK 29.0.2 29.0.2 Installa o configura gli strumenti di build dell'SDK.

Per saperne di più 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 per Build Analyzer di Android Studio

La finestra Build Analyzer ti aiuta a comprendere e diagnosticare i problemi relativi al tuo processo di compilazione, ad esempio le ottimizzazioni disattivate e le 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 già 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 Analisi della build in uno dei seguenti modi:
    • Dopo che Android Studio ha terminato la creazione del progetto, fai clic sulla scheda Build Analyzer.
    • Dopo che Android Studio ha terminato la creazione del progetto, fai clic sul link sul lato destro della finestra Output della build.

La finestra Analisi della build organizza i possibili problemi di build in una struttura ad albero a sinistra. Puoi esaminare e fare clic su ogni problema per visualizzarne 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.

Desugaring della libreria Java 8 in D8 e R8

Il plug-in Android per Gradle ora include il supporto per l'utilizzo di una serie di API del linguaggio Java 8 senza richiedere un livello API minimo per l'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 desugaring è stato esteso per poter eseguire il desugaring delle API del linguaggio Java. Ciò significa che ora puoi includere le API del linguaggio standard disponibili solo nelle versioni recenti di Android (ad esempio java.util.streams) nelle app che supportano le 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 sopra indicate
  • 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 del linguaggio, D8 compila un file DEX di libreria separato che contiene un'implementazione delle API mancanti e lo include nell'app. Il processo di desugaring riscrive il codice dell'app per utilizzare invece questa libreria in fase di runtime.

Per attivare il supporto per queste API del linguaggio, includi quanto segue nel file modulo dell'app build.gradle:

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 il snippet di codice sopra indicato anche nel modulo di libreria's build.gradle file se

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

  • Vuoi eseguire lint sul modulo di libreria in isolamento. In questo modo, lint riconosce gli utilizzi validi delle API del linguaggio ed evita di segnalare avvisi falsi.

Nuove opzioni per attivare o disattivare le funzionalità di build

Il plug-in Android per Gradle 4.0.0 introduce un nuovo modo per controllare le funzionalità di build che vuoi attivare e disattivare, ad esempio 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, il che ti aiuta a ottimizzare il rendimento della build per il tuo progetto. Puoi impostare le opzioni per ogni modulo nel file a livello di modulo build.gradle, come segue:

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 buildFeatures blocco 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 di base dell'app. Quando utilizzi il plug-in Android per Gradle 4.0.0, ora puoi includere un modulo della funzionalità che dipende da un altro modulo della funzionalità. Ovvero, una funzionalità :video può dipendere dalla :camera funzionalità, che dipende dal modulo di base, come mostrato nella figura seguente.

Dipendenze tra funzionalità

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

Ciò significa che quando l'app richiede di scaricare un modulo della funzionalità, scarica anche gli altri moduli della funzionalità da cui dipende. Dopo aver creato moduli di funzionalità per l'app, puoi dichiarare una dipendenza tra funzionalità nel build.gradle file 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à, ad esempio, durante la modifica della configurazione di esecuzione) 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 l'app utilizzando il plug-in Android per Gradle 4.0.0 e versioni successive, il plug-in include i metadati che descrivono le dipendenze compilate nell'app. Quando carichi l'app, Play Console esamina questi metadati per offrirti i seguenti vantaggi:

  • Ricevi avvisi per problemi noti con gli SDK e le dipendenze utilizzati dall'app
  • Ricevi feedback utili per risolvere questi problemi

I dati vengono compressi, criptati da una chiave di firma di Google Play e archiviati nel blocco di firma dell'app di release. Tuttavia, puoi esaminare 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 disattivare questa opzione 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
  }
}

Importare librerie native dalle dipendenze AAR

Ora puoi importare librerie C/C++ dalle dipendenze AAR dell'app. Quando segui i passaggi di configurazione descritti di seguito, Gradle rende automaticamente disponibili queste librerie native per l'utilizzo con il sistema di compilazione 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 utilizzarli.

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 compilazione nativo esterno

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

Ciascuna delle dipendenze AAR dell'app che include codice nativo espone un Android.mk file che devi importare nel progetto ndk-build. Importa questo file utilizzando il comando import&endash;module, che cerca i percorsi specificati utilizzando la proprietà import&endash;add&endash;path nel progetto ndk-build. Ad esempio, se l'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 progetto CMake tramite la variabile CMAKE_FIND_ROOT_PATH{: .external}. Questo valore verrà impostato automaticamente da Gradle quando viene richiamato CMake, quindi se il sistema di compilazione modifica questa variabile, assicurati di aggiungerla anziché assegnarla.

Ogni dipendenza espone un pacchetto di file di configurazione{: .external} alla build CMake, che importi con il find_package{: .external} comando. Questo comando cerca i pacchetti di file di configurazione che corrispondono al nome e alla versione del pacchetto specificati ed espone i target definiti da utilizzare nella build. Ad esempio, se l'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 compilazione nativo esterno collega automaticamente libapp.so contro libcurl.so e impacchetta libcurl.so nell'APK o nell'app bundle. Per ulteriori informazioni, consulta l'esempio di Prefab curl{:.external}.

Modifiche al comportamento

Quando utilizzi questa versione del plug-in, potresti riscontrare le seguenti modifiche al funzionamento.

Aggiornamenti della configurazione di firma v1/v2

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

Firma v1

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

Firma v2

  • Se v2SigningEnabled è attivato in modo esplicito, AGP esegue la firma dell'app v2.
  • Se v2SigningEnabled è disattivato in modo esplicito dall'utente, la firma dell'app v2 non viene eseguita.
  • Se l'utente non ha attivato in modo esplicito 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 in modo esplicito questi flag. Prima di questa release, era possibile che v1Signing venisse disattivato anche se era stato attivato in modo esplicito, il che poteva creare confusione.

Rimozione dei plug-in Android per Gradle feature e instantapp

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 impacchettare le app istantanee utilizzando gli Android App Bundle.

Nel plug-in Android per Gradle 4.0.0 e versioni successive, questi plug-in ritirati sono stati rimossi completamente. Pertanto, per utilizzare l'ultima versione del plug-in Android per Gradle, devi eseguire la migrazione dell'app istantanea per supportare gli Android App Bundle. Eseguendo la migrazione delle app istantanee, puoi sfruttare i vantaggi degli app bundle e semplificare la progettazione modulare dell'app design.

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.

Rimozione della funzionalità di elaborazione delle annotazioni separata

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 venivano utilizzati in progetti solo Java; è stata attivata impostando android.enableSeparateAnnotationProcessing su true nel gradle.properties file, che non funziona più.

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

includeCompileClasspath è ritirato

Il plug-in Android per Gradle non controlla né include più i processori di annotazioni dichiarati nel classpath di compilazione e la annotationProcessorOptions.includeCompileClasspath proprietà DSL 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 questo problema, devi includere i processori di annotazioni nei tuoi build.gradle file utilizzando la annotationProcessor configurazione delle dipendenze. Per saperne di più, leggi Aggiungere processori di annotazioni.

Packaging automatico delle dipendenze precompilate utilizzate da CMake

Le versioni precedenti del plug-in Android per Gradle richiedevano di impacchettare in modo esplicito tutte le librerie precompilate utilizzate dalla build nativa esterna di CMake utilizzando jniLibs. Potresti avere librerie nella src/main/jniLibs directory del 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 sopra indicata non è più necessaria e genererà un errore di build:

* 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 impacchetta automaticamente queste librerie, quindi l'impacchettamento esplicito 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 di Gradle

Le modifiche apportate al plug-in Android per Gradle 4.0 possono attivare una race condition 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 build.

Questo problema verrà risolto in Gradle 6.4.