Plug-in Android 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 le nuove impostazioni e funzionalità predefinite 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 dei pacchetti installati. Per visualizzare un elenco più ampio di app nel sistema, ora devi aggiungere un elemento <queries> nel file manifest Android dell'app o della raccolta.

Il plug-in Android per Gradle 4.1 o versioni successive è già compatibile con la nuova dichiarazione <queries>, ma 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 della tua app.

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

Se utilizzi la
versione AGP...
...esegui l'upgrade a:
4,0.* 4.0.1
3,6.* 3.6.4
3,5.* 3.5.4
3,4.* 3.4.3
3,3.* 3.3.3

Per maggiori 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 per Android Studio Build Analyzer

La finestra Strumento di analisi Build consente di comprendere e diagnosticare i problemi relativi al processo di compilazione, ad esempio la disattivazione delle ottimizzazioni e le attività non configurate correttamente. 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 la tua app selezionando Crea > Crea progetto 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:
    • Al termine della creazione del progetto in Android Studio, fai clic sulla scheda Strumento di analisi Build.
    • Al termine della creazione del progetto in Android Studio, fai clic sul link sul lato destro della finestra Output build.

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

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

Desugaring della libreria Java 8 in D8 e R8

Il plug-in Android Gradle include ora il supporto per l'utilizzo di una serie di API in 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 (ad esempio espressioni lambda, metodi predefiniti di interfaccia, prove con le risorse e altro ancora). In Android Studio 4.0, il motore di desugaring è stato esteso in modo da essere in grado di eliminare le API di linguaggio Java. Ciò significa che ora puoi includere API di lingua standard che erano disponibili solo nelle release recenti di Android (ad esempio java.util.streams) nelle app che supportano versioni precedenti di Android.

In questa release è supportato il seguente set di API:

  • Stream sequenziali (java.util.stream)
  • Un sottoinsieme di java.time
  • java.util.function
  • Aggiunte recenti a java.util.{Map,Collection,Comparator}
  • Facoltativo (java.util.Optional, java.util.OptionalInt e java.util.OptionalDouble) e altri nuovi corsi utili con le API riportate sopra
  • 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 la include nella tua app. Il processo di desugaring riscrive il codice dell'app per utilizzare questa libreria in fase di runtime.

Per abilitare il supporto per queste API di linguaggio, includi quanto segue nel file build.gradle del tuo modulo 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 potrebbe anche essere necessario includere lo snippet di codice riportato sopra nel file build.gradle di un modulo libreria se

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

  • Vuoi eseguire lint sul modulo della libreria in modo isolato. Questo serve a riconoscere gli utilizzi validi delle API di linguaggio ed evitare di segnalare falsi avvisi.

Nuove opzioni per abilitare o disabilitare le funzionalità della build

Il plug-in Android per Gradle 4.0.0 introduce un nuovo modo per controllare le funzionalità della build da attivare e disattivare, ad esempio associazione delle visualizzazioni e associazione dei dati. Quando vengono aggiunte nuove funzionalità, vengono disattivate per impostazione predefinita. Puoi quindi utilizzare il blocco buildFeatures per abilitare solo le funzionalità che preferisci, in modo da ottimizzare le prestazioni della build per il tuo progetto. Puoi impostare le opzioni per ogni modulo nel file build.gradle a livello di modulo 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ù degli elementi seguenti 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 feature-on-feature

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 delle funzionalità che dipende da un altro modulo delle funzionalità. In altre parole, una funzionalità :video può dipendere dalla funzionalità :camera, che dipende dal modulo di base, come mostrato nella figura seguente.

Funzionalità sulle dipendenze per le funzionalità

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

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

// 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, dovresti abilitare la funzionalità di dipendenza in base alle funzionalità in Android Studio (ad esempio per supportare la funzionalità durante la modifica della configurazione di esecuzione) facendo clic su Guida > Modifica opzioni VM personalizzate nella 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. Durante il caricamento dell'app, Play Console esamina questi metadati per offrirti i seguenti vantaggi:

  • Ricevi avvisi sui problemi noti relativi agli SDK e alle dipendenze usate dalla tua app
  • Ricevere feedback utili per risolvere questi problemi

I dati vengono compressi, criptati con una chiave di firma di Google Play e archiviati nel blocco di firma della release dell'app. Tuttavia, puoi controllare autonomamente 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 da 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 tuo sistema di build nativo esterno, come CMake. Tieni presente che Gradle rende disponibili queste librerie solo per la tua build; devi comunque configurare gli script di build per utilizzarle.

Le librerie vengono esportate utilizzando il formato del pacchetto prefabbricato.

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

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

Configura il tuo sistema di compilazione nativo esterno

Per vedere i passaggi da seguire, segui quelli riportati di seguito per il sistema di build nativo esterno che intendi utilizzare.

Ognuna delle dipendenze AAR dell'app che include il codice nativo espone un file Android.mk che devi importare nel progetto ndk-build. Puoi importare 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 sono 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 tuo sistema di build modifica questa variabile, assicurati di aggiungerla anziché assegnarla.

Ogni dipendenza espone un pacchetto di config-file{: .external} alla tua build CMake, che importerai con il comando find_package{: .external}. Questo comando cerca i pacchetti del file config che corrispondono al nome e alla versione del pacchetto specificati ed espone le destinazioni che deve essere utilizzato 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 tuo progetto, il sistema di compilazione nativo esterno collega automaticamente libapp.so a libcurl.so e pacchettizza libcurl.so nell'APK o nell'app bundle. Per ulteriori informazioni, consulta l'articolo curl prefab sample{:.external}.

Modifiche del comportamento

Quando utilizzi questa versione del plug-in, potresti riscontrare i seguenti cambiamenti di comportamento.

Aggiornamenti della configurazione della firma v1/v2

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

firma v1

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

firma v2

  • Se v2SigningEnabled è abilitato esplicitamente, AGP esegue la firma dell'app v2.
  • Se v2SigningEnabled viene disattivato esplicitamente dall'utente, la firma dell'app v2 non viene eseguita.
  • Se l'utente non ha abilitato esplicitamente la firma v2, è possibile disattivarla automaticamente in base a targetSdk.

Queste modifiche consentono ad AGP di ottimizzare le build disabilitando il meccanismo di firma a seconda che l'utente abbia abilitato esplicitamente questi flag. Prima di questa release, era possibile disabilitare v1Signing anche quando era abilitato esplicitamente, il che potrebbe creare confusione.

Plug-in Android per Gradle feature e instantapp rimossi

Il plug-in Android Gradle 3.6.0 ha ritirato il plug-in delle funzionalità (com.android.feature) e il plug-in delle app istantanee (com.android.instantapp) in favore dell'utilizzo del plug-in di 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 deprecati vengono completamente rimossi. Pertanto, per utilizzare il plug-in Android Gradle più recente, devi eseguire la migrazione della tua app istantanea in modo che supporti gli Android App Bundle. Eseguendo la migrazione delle tue app istantanee, puoi sfruttare i vantaggi degli app bundle e semplificare la progettazione modulare della tua app.

Nota: per aprire progetti che utilizzano i plug-in rimossi in Android Studio 4.0 e versioni successive, i progetti devono 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 è stata utilizzata per mantenere la compilazione Java incrementale quando vengono utilizzati processori di annotazione non incrementali nei progetti solo Java. È stata abilitata impostando android.enableSeparateAnnotationProcessing su true nel file gradle.properties, che non funziona più.

Devi invece eseguire la migrazione all'utilizzo di processori di annotazione incrementali per migliorare le prestazioni della build.

L'API includeCompileClasspath è deprecata

Il plug-in Android Gradle non controlla più o include i processori di annotazioni dichiarati nel classpath di compilazione e la proprietà DSL annotationProcessorOptions.includeCompileClasspath non ha più alcun effetto. Se includi 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 annotazione nei tuoi file build.gradle utilizzando la configurazione delle dipendenze annotationProcessor. Per saperne di più, consulta Aggiungere processori di annotazione.

Pacchettizzazione automatica delle dipendenze predefinite utilizzata da CMake

Le versioni precedenti del plug-in Android per Gradle richiedevano l'esplicita pacchetto delle librerie predefinite utilizzate dalla build nativa esterna di CMake mediante jniLibs. Potrebbero esserci librerie nella directory src/main/jniLibs del modulo o in qualche 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 di cui sopra 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'

Ora la build nativa esterna pacchettizza automaticamente queste librerie, quindi pacchettizzare esplicitamente la libreria con jniLibs genera un duplicato. Per evitare l'errore di compilazione, sposta la libreria predefinita in una posizione esterna a jniLibs o rimuovi la configurazione jniLibs dal file build.gradle.

Problemi noti

Questa sezione descrive i problemi noti che esistono nel plug-in Android Gradle 4.0.0.

Condizione di gara nel meccanismo worker Gradle

Le modifiche apportate al plug-in Android per Gradle 4.0 possono attivare una condizione di gara in Gradle se 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.