Panoramica di Play Feature Delivery

Il modello di pubblicazione delle app di Google Play utilizza gli Android App Bundle per generare e pubblicare APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che gli utenti scarichino solo il codice e le risorse di cui hanno bisogno per eseguire la tua app.

Play Feature Delivery utilizza le funzionalità avanzate degli app bundle, consentendo di caricare alcune funzionalità della tua app in base alle condizioni o di scaricarle on demand. Per farlo, devi prima separare queste funzionalità dall'app di base in moduli di funzionalità.

Configurazione di compilazione del modulo della funzionalità

Quando crei un nuovo modulo di funzionalità utilizzando Android Studio, l'IDE applica il seguente plug-in Gradle al file build.gradle del modulo.

// The following applies the dynamic-feature plugin to your feature module.
// The plugin includes the Gradle tasks and properties required to configure and build
// an app bundle that includes your feature module.

plugins {
  id 'com.android.dynamic-feature'
}

Molte delle proprietà disponibili per il plug-in dell'applicazione standard sono disponibili anche per il modulo della funzionalità. Le seguenti sezioni descrivono le proprietà che dovresti e non dovresti includere nella configurazione della build del tuo modulo delle funzionalità.

Elementi da escludere nella configurazione di compilazione del modulo della funzionalità

Poiché ogni modulo delle funzionalità dipende dal modulo di base, eredita anche determinate configurazioni. Devi quindi omettere quanto segue nel file build.gradle del modulo della funzionalità:

  • Configurazioni di firma:gli app bundle vengono firmati utilizzando le configurazioni di firma specificate nel modulo di base.
  • La proprietà minifyEnabled: puoi abilitare la riduzione del codice per l'intero progetto dell'app solo dalla configurazione della build del modulo di base. Dovresti quindi omettere questa proprietà dai moduli delle caratteristiche. Tuttavia, puoi specificare regole ProGuard aggiuntive per ogni modulo di funzionalità.
  • versionCode e versionName: durante la creazione dell'app bundle, Gradle utilizza le informazioni sulla versione dell'app fornite dal modulo di base. Devi omettere queste proprietà dal file build.gradle del modulo di funzionalità.

Stabilire una relazione con il modulo di base

Quando Android Studio crea il modulo delle funzionalità, lo rende visibile al modulo di base aggiungendo la proprietà android.dynamicFeatures al file build.gradle del modulo di base, come mostrato di seguito:

// In the base module’s build.gradle file.
android {
    ...
    // Specifies feature modules that have a dependency on
    // this base module.
    dynamicFeatures = [":dynamic_feature", ":dynamic_feature2"]
}

Inoltre, Android Studio include il modulo di base come dipendenza del modulo della funzionalità, come mostrato di seguito:

// In the feature module’s build.gradle file:
...
dependencies {
    ...
    // Declares a dependency on the base module, ':app'.
    implementation project(':app')
}

Specifica regole ProGuard aggiuntive

Sebbene solo la configurazione di build del modulo di base possa attivare la riduzione del codice per il progetto dell'app, puoi fornire regole ProGuard personalizzate con ogni modulo di funzionalità utilizzando la proprietà proguardFiles, come mostrato di seguito.

android.buildTypes {
     release {
         // You must use the following property to specify additional ProGuard
         // rules for feature modules.
         proguardFiles 'proguard-rules-dynamic-features.pro'
     }
}

Tieni presente che queste regole ProGuard vengono unite a quelle di altri moduli (incluso il modulo di base) in fase di creazione. Pertanto, anche se ogni modulo di funzionalità può specificare un nuovo insieme di regole, queste regole si applicano a tutti i moduli del progetto dell'app.

Esegui il deployment dell'app

Durante lo sviluppo dell'app con il supporto dei moduli di funzionalità, puoi eseguire il deployment dell'app su un dispositivo connesso come faresti normalmente selezionando Esegui > Esegui dalla barra dei menu (o facendo clic su Esegui nella barra degli strumenti).

Se il progetto dell'app include uno o più moduli delle funzionalità, puoi scegliere quali includere durante il deployment dell'app modificando la configurazione di esecuzione/debug esistente come segue:

  1. Seleziona Esegui > Modifica configurazioni dalla barra dei menu.
  2. Nel riquadro a sinistra della finestra di dialogo Configurazioni esecuzione/debug, seleziona la configurazione dell'app per Android che preferisci.
  3. In Funzionalità dinamiche da implementare nella scheda Generali, seleziona la casella accanto a ogni modulo di funzionalità da includere durante l'implementazione dell'app.
  4. Fai clic su OK.

Per impostazione predefinita, Android Studio non esegue il deployment dell'app utilizzando gli app bundle. L'IDE, infatti, compila e installa sul dispositivo APK ottimizzati per la velocità di deployment, anziché per le dimensioni. Per configurare Android Studio in modo da creare e implementare invece APK ed esperienze istantanee da un app bundle, modifica la configurazione di esecuzione/debug.

Utilizza i moduli delle funzionalità per una pubblicazione personalizzata

Un vantaggio esclusivo dei moduli delle funzionalità è la possibilità di personalizzare come e quando funzionalità diverse della tua app vengono scaricate sui dispositivi con Android 5.0 (livello API 21) o versioni successive. Ad esempio, per ridurre le dimensioni di download iniziali della tua app, puoi configurare alcune funzionalità in modo che vengano scaricate on demand in base alle necessità oppure soltanto su dispositivi che le supportano, ad esempio la possibilità di scattare foto o supportare le funzionalità di realtà aumentata.

Sebbene tu ottenga download altamente ottimizzati per impostazione predefinita quando carichi la tua app come app bundle, le opzioni di pubblicazione delle funzionalità più avanzate e personalizzabili richiedono una configurazione e una modularizzazione aggiuntive delle funzionalità dell'app tramite i moduli delle funzionalità. In altre parole, i moduli di funzionalità forniscono i componenti di base per creare funzionalità modulari che puoi configurare in modo che ciascuna possa essere scaricata in base alle esigenze.

Prendi ad esempio un'app che consente agli utenti di acquistare e vendere prodotti in un marketplace online. Puoi modularizzare ragionevolmente ciascuna delle seguenti funzionalità dell'app in moduli di funzionalità distinti:

  • Accesso e creazione dell'account
  • Esplorazione del marketplace
  • Mettere un articolo in vendita
  • Elaborazione dei pagamenti

La tabella seguente descrive le diverse opzioni di caricamento supportate dai moduli di funzionalità e come possono essere utilizzate per ottimizzare le dimensioni del download iniziale dell'app marketplace di esempio.

Opzione di consegna Comportamento Caso d'uso di esempio Per iniziare
Pubblicazione al momento dell'installazione Per impostazione predefinita, i moduli delle funzionalità che non configurano nessuna delle opzioni di pubblicazione descritte sopra vengono scaricati al momento dell'installazione dell'app. Si tratta di un comportamento importante perché ti consente di adottare gradualmente le opzioni di pubblicazione avanzate. Ad esempio, puoi trarre vantaggio dalla modularizzazione delle funzionalità della tua app e attivare il caricamento on demand solo dopo aver implementato completamente i download on demand utilizzando la Play Feature Delivery Library.

Inoltre, l'app può richiedere la disinstallazione delle funzionalità in un secondo momento. Pertanto, se hai bisogno di determinate funzionalità al momento dell'installazione dell'app, ma non dopo, puoi ridurre le dimensioni di installazione richiedendo la rimozione della funzionalità dal dispositivo.

Se l'app prevede determinate attività di formazione, ad esempio una guida interattiva su come acquistare e vendere articoli nel marketplace, puoi includere questa funzionalità al momento dell'installazione dell'app per impostazione predefinita.

Tuttavia, per ridurre le dimensioni installate dell'app, l'app può richiedere di eliminare la funzionalità dopo che l'utente ha completato la formazione.

Modularizza la tua app utilizzando moduli di funzionalità che non configurano opzioni di distribuzione avanzate.

Per scoprire come ridurre le dimensioni installate della tua app rimuovendo determinati moduli di funzionalità che l'utente potrebbe non aver più bisogno, leggi Gestire i moduli installati.

Pubblicazione on demand Consente alla tua app di richiedere e scaricare i moduli di funzionalità in base alle necessità. Se solo il 20% di chi utilizza l'app marketplace pubblica articoli in vendita, una buona strategia per ridurre le dimensioni del download iniziale per la maggior parte degli utenti è rendere disponibile la funzionalità di acquisizione di foto, compresa la descrizione di un articolo, e la messa in vendita di un articolo come download on demand. In altre parole, puoi configurare il modulo della funzionalità di vendita dell'app in modo che venga scaricato solo quando un utente mostra interesse a mettere in vendita articoli sul marketplace.

Inoltre, se l'utente non vende più articoli dopo un determinato periodo di tempo, l'app può ridurre le dimensioni installate chiedendo di disinstallare la funzionalità.

Crea un modulo delle funzionalità e configura il caricamento on demand. La tua app può quindi utilizzare la libreria Play Feature Delivery per richiedere di scaricare il modulo on demand.
Pubblicazione condizionale Consente di specificare determinati requisiti del dispositivo dell'utente, come funzionalità hardware, impostazioni internazionali e livello API minimo, per determinare se una funzionalità modularizzata viene scaricata al momento dell'installazione dell'app. Se l'app marketplace ha una copertura globale, potresti dover supportare metodi di pagamento popolari solo in determinate regioni o località. Per ridurre le dimensioni di download iniziali dell'app, puoi creare moduli di funzionalità separati per l'elaborazione di determinati tipi di metodi di pagamento e installarli in modo condizionale sul dispositivo di un utente in base alla sua lingua registrata. Crea un modulo della funzionalità e configura la pubblicazione condizionale.
Consegna istantanea Google Play Instant consente agli utenti di interagire con la tua app senza doverla installare sul proprio dispositivo. Invece, possono provare la tua app tramite il pulsante "Prova ora" sul Google Play Store o un URL creato da te. Questa forma di pubblicazione di contenuti ti consente di aumentare più facilmente il coinvolgimento con la tua app.

Con la distribuzione istantanea, puoi utilizzare Google Play Instant per consentire agli utenti di sperimentare immediatamente determinate funzionalità della tua app senza installazione.

Prendi in considerazione un gioco che includa i primi livelli in un modulo di funzionalità leggero. Puoi attivare immediatamente il modulo in modo che gli utenti possano provare immediatamente il gioco tramite un link URL o il pulsante "Prova ora", senza installare l'app. Crea un modulo di funzionalità e configura la distribuzione istantanea. L'app può quindi utilizzare la libreria Play Feature Delivery per richiedere di scaricare il modulo on demand.

Tieni presente che la modularizzazione delle funzionalità dell'app tramite i moduli delle funzionalità è solo il primo passaggio. Per supportare Google Play Instant, le dimensioni del download del modulo di base della tua app e di una determinata funzionalità abilitata per l'istantaneità devono soddisfare rigide limitazioni di dimensioni. Per saperne di più, consulta Attivare le esperienze istantanee riducendo le dimensioni dell'app o del gioco.

Creazione di un URI per una risorsa

Se vuoi accedere a una risorsa archiviata in un modulo di funzionalità utilizzando un URI, ecco come generare un URI di risorsa del modulo di funzionalità utilizzando Uri.Builder():

Kotlin

val uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build()

Java

String uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build().toString();

Ogni parte del percorso alla risorsa viene costruita in fase di esecuzione, assicurando che lo spazio dei nomi corretto venga generato dopo il caricamento degli APK suddivisi.

Come esempio di come viene generato l'URI, supponiamo di avere un'app e moduli di funzionalità con i seguenti nomi:

  • Nome pacchetto dell'app: com.example.my_app_package
  • Nome del pacchetto delle risorse della funzionalità: com.example.my_app_package.my_dynamic_feature

Se resId nello snippet di codice riportato sopra si riferisce a una risorsa di file non elaborata denominata "my_video" nel modulo della funzionalità, il codice Uri.Builder() riportato sopra restituirà il seguente risultato:

android.resource://com.example.my_app_package/raw/com.example.my_app_package.my_dynamic_feature:my_video

Questo URI può essere utilizzato dalla tua app per accedere alla risorsa del modulo della funzionalità.

Per convalidare i percorsi nell'URI, puoi utilizzare lo Strumento di analisi APK per esaminare l'APK del modulo delle funzionalità e determinare il nome del pacchetto:

Uno screenshot di APK Analyzer che esamina i contenuti di un file di risorse compilato.

Figura 2. Utilizza APK Analyzer per ispezionare il nome del pacchetto in un file di risorse compilato.

Considerazioni sui moduli delle funzionalità

Con i moduli di funzionalità, puoi migliorare la velocità di compilazione e la velocità di ingegnerizzazione e personalizzare ampiamente la distribuzione delle funzionalità dell'app per ridurne le dimensioni. Tuttavia, ci sono alcuni vincoli e casi limite da tenere presenti quando si utilizzano i moduli delle caratteristiche:

  • L'installazione di 50 o più moduli di funzionalità su un singolo dispositivo, tramite distribuzione condizionale o on demand, potrebbe causare problemi di prestazioni. I moduli al momento dell'installazione, che non sono configurati come rimovibili, vengono inclusi automaticamente nel modulo di base e conteggiati come un solo modulo delle funzionalità su ogni dispositivo.
  • Limita il numero di moduli configurati come rimovibili per il caricamento al momento dell'installazione a 10 o meno. In caso contrario, il tempo di download e installazione dell'app potrebbe aumentare.
  • Solo i dispositivi con Android 5.0 (livello API 21) e versioni successive supportano il download e l'installazione delle funzionalità on demand. Per rendere disponibile la tua funzionalità per le versioni precedenti di Android, abilita Fusing quando crei un modulo di funzionalità.
  • Abilita SplitCompat, in modo che la tua app abbia accesso ai moduli delle funzionalità scaricati che vengono forniti on demand.
  • I moduli di funzionalità non devono specificare attività nel file manifest con android:exported impostato su true. Questo perché non c'è alcuna garanzia che il dispositivo abbia scaricato il modulo della funzionalità quando un'altra app tenta di avviare l'attività. Inoltre, l'app deve confermare che una funzionalità è stata scaricata prima di tentare di accedere al relativo codice e alle relative risorse. Per scoprire di più, consulta Gestire i moduli installati.
  • Poiché Play Feature Delivery richiede la pubblicazione dell'app tramite un app bundle, assicurati di essere a conoscenza dei problemi noti relativi all'app bundle.

Riferimento manifest del modulo della funzionalità

Quando crei un nuovo modulo di funzionalità utilizzando Android Studio, l'IDE include la maggior parte degli attributi del file manifest necessari al modulo per comportarsi come un modulo di funzionalità. Inoltre, alcuni attributi vengono inseriti dal sistema di compilazione in fase di compilazione, quindi non è necessario specificarli o modificarli manualmente. La tabella seguente descrive gli attributi manifest importanti per i moduli di funzionalità.

Attributo Descrizione
<manifest
...
Questo è il tuo blocco <manifest> tipico.
xmlns:dist="http://schemas.android.com/apk/distribution" Specifica un nuovo spazio dei nomi XML dist: descritto più dettagliatamente di seguito.
split="split_name" Quando Android Studio crea il tuo app bundle, include automaticamente questo attributo. Pertanto, non devi includere o modificare personalmente questo attributo.

Definisce il nome del modulo, che la tua app specifica quando viene richiesto un modulo on demand utilizzando la libreria Play Feature Delivery.

In che modo Gradle determina il valore di questo attributo:

Per impostazione predefinita, quando crei un modulo di funzionalità utilizzando Android Studio, l'IDE utilizza il valore specificato come Nome del modulo per identificare il modulo come sottoprogetto Gradle nel file delle impostazioni Gradle.

Quando crei l'app bundle, Gradle utilizza l'ultimo elemento del percorso del sottoprogetto per iniettare questo attributo manifest nel manifest del modulo. Ad esempio, se crei un nuovo modulo di funzionalità nella directory MyAppProject/features/ e hai specificato " dynamic_feature1 come Nome modulo, l'IDE aggiunge ':features:dynamic_feature1' come sottoprogetto nel tuo file settings.gradle. Quando crei il bundle dell'app, Gradle inietta <manifest split="dynamic_feature1"> nel file manifest del modulo.

android:isFeatureSplit="true | false"> Quando Android Studio crea l'app bundle, include automaticamente questo attributo. Pertanto, non devi includere o modificare manualmente questo attributo.

Specifica che questo modulo è un modulo delle funzionalità. I manifest nei moduli di base e negli APK di configurazione omettono questo attributo o lo impostano su false.

<dist:module Questo nuovo elemento XML definisce gli attributi che determinano la modalità di pacchettizzamento e distribuzione del modulo come APK.
dist:instant="true | false" Specifica se il modulo deve essere disponibile tramite Google Play Instant come un'esperienza istantanea.

Se la tua app include uno o più moduli delle funzionalità attivati istantaneamente, devi attivare istantaneamente anche il modulo di base. Quando utilizzi Android Studio 3.5 o versioni successive, l'IDE esegue questa operazione per te quando crei un modulo di funzionalità abilitato all'istante.

Non puoi impostare questo elemento XML su true e anche su <dist:on-demand/>. Tuttavia, puoi comunque richiedere i download on demand dei moduli delle funzionalità attivati in modo istantaneo come app istantanee utilizzando la Play Feature Delivery Library. Quando un utente scarica e installa la tua app, il dispositivo scarica e installa i moduli di funzionalità ad attivazione istantanea della tua app, insieme all'APK di base, per impostazione predefinita.

dist:title="@string/feature_name" Specifica un titolo rivolto agli utenti per il modulo. Ad esempio, il dispositivo potrebbe visualizzare questo titolo quando richiede la conferma del download.

Devi includere la risorsa stringa per questo titolo nel file module_root/src/source_set/res/values/strings.xml del modulo di base.

<dist:fusing dist:include="true | false" />
</dist:module>
Specifica se includere il modulo in APK multipli destinati ai dispositivi con Android 4.4 (livello API 20) e versioni precedenti.

Inoltre, quando utilizzi bundletool per generare APK da un app bundle, solo i moduli di funzionalità che impostano questa proprietà su true sono inclusi nell'APK universale, ovvero un APK monolitico che include codice e risorse per tutte le configurazioni del dispositivo supportate dalla tua app.

<dist:delivery> Incapsula le opzioni che personalizza l'importazione dei moduli, come mostrato di seguito. Tieni presente che ogni modulo della funzionalità deve configurare un solo tipo di queste opzioni di pubblicazione personalizzata.
<dist:install-time> Specifica che il modulo deve essere disponibile al momento dell'installazione. Questo è il comportamento predefinito per i moduli di funzionalità che non specificano un altro tipo di opzione di pubblicazione personalizzata.

Per scoprire di più sui download al momento dell'installazione, consulta Configurare il caricamento al momento dell'installazione.

Questo nodo può anche specificare condizioni che limitano il modulo ai dispositivi che soddisfano determinati requisiti, ad esempio funzionalità del dispositivo, paese dell'utente o livello API minimo. Per saperne di più, consulta Configurare la pubblicazione condizionale.

<dist:removable dist:value="true | false" />

Se non è impostato o se è impostato su false, bundletool unisce i moduli al momento dell'installazione nel modulo di base durante la generazione di APK suddivisi dal bundle. Poiché l'unione avrà meno APK divisi, questa impostazione potrebbe migliorare le prestazioni della tua app.

Se il criterio removable viene impostato su true: i moduli al momento dell'installazione non verranno integrati nel modulo di base. Imposta su true se vuoi disinstallare i moduli in futuro. Tuttavia, la configurazione di troppi moduli da rimuovere potrebbe aumentare il tempo di installazione dell'app.

Il valore predefinito è false. È necessario impostare questo valore nel manifest solo se vuoi disabilitare l'unione per un modulo di funzionalità.

Nota: questa funzionalità è disponibile solo se si utilizza il plug-in Android Gradle 4.2 o quando si utilizza bundletool v1.0 dalla riga di comando.

</dist:install-time>  
<dist:on-demand/> Specifica che il modulo deve essere disponibile come download on demand. In altre parole, il modulo non è disponibile al momento dell'installazione, ma la tua app potrebbe richiedere di scaricarlo in un secondo momento.

Per scoprire di più sui download on demand, consulta Configurare il caricamento on demand.

</dist:delivery>
<application
android:hasCode="true | false">
...
</application>
Se il modulo della funzionalità non genera file DEX, ovvero non contiene codice che viene successivamente compilato nel formato file DEX, devi eseguire quanto segue (in caso contrario, potresti ricevere errori di runtime):
  1. Imposta android:hasCode su "false" nel manifest del modulo della funzionalità.
  2. Aggiungi quanto segue al manifest del modulo base:
    <application
      android:hasCode="true"
      tools:replace="android:hasCode">
      ...
    </application>

Risorse aggiuntive

Per scoprire di più sull'utilizzo dei moduli di funzionalità, prova le seguenti risorse.

Post del blog

Video

Termini di servizio e sicurezza dei dati

Se accedi alla Play Feature Delivery Library o la utilizzi, accetti i Termini di servizio del kit di sviluppo software Play Core. Prima di accedere alla raccolta, leggete e comprendete tutti i termini e le norme vigenti.

Sicurezza dei dati

Le librerie Play Core sono l'interfaccia di runtime della tua app con il Google Play Store. Pertanto, quando utilizzi Play Core nella tua app, il Play Store esegue le proprie procedure, che includono il trattamento dei dati ai sensi dei Termini di servizio di Google Play. Le informazioni riportate di seguito descrivono il modo in cui le librerie Play Core gestiscono i dati per elaborare richieste specifiche della tua app.

API Additional Language

Dati raccolti sull'utilizzo Elenco delle lingue installate
Scopo della raccolta dei dati I dati raccolti vengono utilizzati per fornire versioni dell'app in lingue diverse e per conservare le lingue installate dopo un aggiornamento dell'app.
Crittografia dei dati I dati sono criptati.
Condivisione dei dati I dati non vengono trasferiti a terze parti.
Eliminazione dei dati I dati vengono eliminati al termine di un periodo di conservazione fisso.

Play Feature Delivery

Dati raccolti sull'utilizzo Metadati del dispositivo
Versione dell'applicazione
Scopo della raccolta dei dati I dati raccolti vengono utilizzati per fornire il modulo corretto al dispositivo e per preservare i moduli installati dopo un aggiornamento, un backup e un ripristino.
Crittografia dei dati I dati sono criptati.
Condivisione dei dati I dati non vengono trasferiti a terze parti.
Eliminazione dei dati I dati vengono eliminati dopo un periodo di conservazione fisso.

Cerchiamo di essere il più trasparenti possibili, ma sei l'unico responsabile della decisione su come rispondere al modulo della sezione Sicurezza dei dati di Google Play per quanto riguarda le modalità di raccolta, condivisione e sicurezza dei dati utente della tua app.