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 minore supporta la compatibilità con le nuove impostazioni predefinite e le nuove funzionalità per la visibilità del pacchetto 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 Android manifest della tua app o libreria.

Il plug-in Android per Gradle 4.1 e versioni successive è 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 per Android 11, potresti riscontrare errori di unione del file manifest durante la compilazione dell'app.

Per risolvere il problema, stiamo rilasciando un insieme di patch per AGP 3.3 e versioni superiori. 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 compilazione dell'SDK.

Per ulteriori informazioni su questa nuova funzionalità, consulta Visibilità del pacchetto 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 del build ti aiuta a comprendere e diagnosticare i problemi relativi al processo di compilazione, ad esempio le ottimizzazioni disattivate e le attività configurate in modo errato. Questa funzionalità è disponibile se utilizzi Android Studio 4.0 e versioni successive con il plug-in Android Gradle 4.0.0 e versioni successive. Puoi aprire la finestra Analisi build da Android Studio nel seguente modo:

  1. Se non l'hai ancora fatto, compila l'app selezionando Compila > Crea progetto dalla barra dei menu.
  2. Seleziona Visualizza > Finestre degli strumenti > Build dalla barra dei menu.
  3. Nella finestra Compilazione, apri la finestra Strumento di analisi compilazione in uno dei modi seguenti:
    • Al termine della compilazione del progetto in Android Studio, fai clic sulla scheda Annalizzatore compilazione.
    • Una volta che Android Studio ha completato la compilazione del progetto, fai clic sul link sul lato destro della finestra Output della compilazione.

La finestra Strumento di analisi della build organizza i possibili problemi di build in un albero a sinistra. Puoi esaminare e fare clic su ogni problema per esaminarne i dettagli nel riquadro a destra. Quando Android Studio analizza la compilazione, calcola l'insieme di attività che hanno determinato la durata della compilazione 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 scoprire di più, vedi Identificare le regressioni della velocità di compilazione.

Desugaring delle librerie Java 8 in D8 e R8

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

Attraverso un processo chiamato desugaring, il compilatore DEX, D8, in Android Studio 3.0 e versioni successive ha già fornito un supporto sostanziale per le funzionalità del linguaggio Java 8 (come espressioni lambda, metodi di interfaccia predefiniti, prova con risorse e altro ancora). In Android Studio 4.0, il motore di desugaring è stato esteso in modo da poter eseguire il desugaring delle API del linguaggio Java. Ciò significa che ora puoi includere API di lingua standard disponibili solo nelle release Android recenti (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
  • Aggiunta di recente a java.util.{Map,Collection,Comparator}
  • Facoltativi (java.util.Optional, java.util.OptionalInt e java.util.OptionalDouble) e alcune altre nuove classi utili con le API sopra riportate
  • 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 della libreria separato che contiene un'implementazione delle API mancanti e lo include nella tua app. Il processo di desugaring riscrive il codice dell'app in modo da utilizzare questa libreria in fase di esecuzione.

Per abilitare il supporto di queste API di linguaggio, 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 instrumentati del modulo della libreria utilizzano queste API di linguaggio (direttamente o tramite il modulo della libreria o le sue dipendenze). In questo modo, le API mancanti vengono fornite per l'APK di test strumentato.

  • Vuoi eseguire lint sul modulo della libreria in isolamento. Lo scopo è aiutare il lint a riconoscere gli utilizzi validi delle API di linguaggio ed evitare di segnalare falsi avvisi.

Nuove opzioni per attivare o disattivare le funzionalità di compilazione

Il plug-in Android per Gradle 4.0.0 introduce un nuovo modo per controllare le funzionalità di compilazione 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 e ottimizzare il rendimento della compilazione 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ù 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 di 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 di funzionalità che dipende da un altro modulo di funzionalità. In altre parole, una funzionalità :video può dipendere dalla funzionalità :camera, che dipende dal modulo di base, come mostrato nella figura seguente.

Dipendenze delle 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à, scarica anche gli altri moduli di funzionalità di cui dipende. Dopo aver creato moduli di 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 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, devi attivare la funzionalità di dipendenza delle funzionalità in Android Studio (per supportarla, ad esempio, 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 l'app utilizzando il plug-in Android Gradle 4.0.0 e versioni successive, il plug-in include metadati che descrivono le dipendenze compilate nell'app. Quando carichi l'app, Play Console ispeziona questi metadati per offrirti i seguenti vantaggi:

  • Ricevi avvisi relativi a problemi noti con gli SDK e le 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 release. Tuttavia, puoi ispezionare i metadati autonomamente 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 la funzionalità includendo quanto segue nel file build.gradle del tuo 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 le librerie native dalle dipendenze AAR

Ora puoi importare le 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 essere impiegate con il sistema di compilazione nativo esterno, ad esempio CMake. Tieni presente che Gradle rende disponibili queste librerie solo per la compilazione; devi comunque configurare gli script di compilazione 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 condivisa, statica o solo di intestazione.

In genere, il nome del pacchetto corrisponde al nome dell'elemento 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 conoscere i passaggi da seguire, segui quelli indicati di seguito per il sistema di compilazione nativo esterno che intendi utilizzare.

Ognuna 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 esegue la ricerca nei percorsi specificati 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 file 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 tuo sistema di compilazione modifica questa variabile, assicurati di aggiungerla anziché assegnarla.

Ogni dipendenza espone un pacchetto file di configurazione{: .external} alla compilazione CMake, che importi con il comando find_package{: .external}. Questo comando cerca i pacchetti di file di configurazione corrispondenti al nome e alla versione del pacchetto specificati ed espone i target che definisce da utilizzare nella compilazione. Ad esempio, se la tua applicazione definisce libapp.so e utilizza curl, devi includere quanto segue nel CMakeLists.txt file:


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 esegui la compilazione del 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'esempio di prefab curl{:.external}.

Modifiche al comportamento

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

Aggiornamenti alla configurazione della firma v1/v2

Il comportamento delle configurazioni di firma dell'app nel blocco signingConfig è stato modificato nel seguente modo:

Firma v1

  • Se v1SigningEnabled è abilitato esplicitamente, 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 è attivato 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 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 esplicitamente questi flag. Prima di questa release, era possibile che v1Signing fosse disattivato anche se attivato esplicitamente, 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) in favore dell'utilizzo del plug-in delle funzionalità dinamiche (com.android.dynamic-feature) per compilare 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 vengono rimossi completamente. Pertanto, per utilizzare il plug-in Gradle per Android più recente, devi eseguire la migrazione della tua app istantanea per supportare gli Android App Bundle. Eseguendo la migrazione delle app istantanee, puoi sfruttare i vantaggi degli app bundle e semplificare il design 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 Gradle 3.6.0 o versioni precedenti.

È stata rimossa la funzionalità di elaborazione separata delle annotazioni

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

Dovresti invece eseguire la migrazione all'utilizzo di elaboratori di annotazioni incrementali per migliorare il rendimento della compilazione.

includeCompileClasspath è deprecato

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

Imballaggio automatico delle dipendenze predefinite utilizzate da CMake

Le versioni precedenti del plug-in Android per Gradle richiedevano di impacchettare esplicitamente tutte le librerie precompilate utilizzate dalla compilazione 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 sopra indicata 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 compilazione nativa esterna ora pacchettizza automaticamente queste librerie, pertanto il pacchettizzazione esplicita della libreria con jniLibs genera un duplicato. Per evitare l'errore di compilazione, sposta la libreria precompilata in una posizione al di fuori di jniLibs o rimuovi la configurazione jniLibs dal file build.gradle.

Problemi noti

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

Condizione di gara nel meccanismo del worker di Gradle

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

Questo problema verrà risolto in Gradle 6.4.