Gli utenti spesso evitano di scaricare app che sembrano troppo grandi, soprattutto nei mercati emergenti, dove i dispositivi si connettono a reti 2G e 3G instabili o funzionano con piani con limiti di dati. Questa pagina descrive come ridurre le dimensioni del download della tua app, in modo che un maggior numero di utenti possa scaricarla.
Caricare l'app con Android App Bundle
Carica la tua app come Android App Bundle per ridurre immediatamente le dimensioni dell'app quando la pubblichi su Google Play. Android App Bundle è un formato di caricamento che include tutto il codice e le risorse compilati della tua app, ma rimanda la generazione e la firma dell'APK a Google Play.
Il modello di pubblicazione delle app di Google Play utilizza poi l'app bundle per generare e pubblicare APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che scarichi solo il codice e le risorse necessari per eseguire l'app. Non devi creare, firmare e gestire più APK per supportare dispositivi diversi e gli utenti ottengono download più piccoli e ottimizzati.
Google Play applica una limitazione delle dimensioni di download compresso di 200 MB per le app pubblicate con app bundle. È possibile utilizzare dimensioni maggiori con Play Feature Delivery e Play Asset Delivery, ma l'aumento delle dimensioni dell'app può influire negativamente sulla riuscita dell'installazione e aumentare le disinstallazioni, pertanto ti consigliamo di applicare le linee guida descritte in questa pagina per ridurre il più possibile le dimensioni di download dell'app.
Comprendere la struttura dell'APK
Prima di ridurre le dimensioni dell'app, è utile comprendere la struttura dell'APK di un'app. Un file APK è costituito da un archivio ZIP che contiene tutti i file che compongono l'app. Questi file includono file di classe Java, file di risorse e un file contenente le risorse compilate.
Un APK contiene le seguenti directory:
META-INF/
: contiene i file di firmaCERT.SF
eCERT.RSA
, nonché il file manifestMANIFEST.MF
.assets/
: contiene gli asset dell'app, che l'app può recuperare utilizzando un oggettoAssetManager
.res/
: contiene risorse che non sono compilate inresources.arsc
.lib/
: contiene il codice compilato specifico del livello software di un processore. Questa directory contiene una sottodirectory per ogni tipo di piattaforma, ad esempioarmeabi
,armeabi-v7a
,arm64-v8a
,x86
,x86_64
emips
.
Un APK contiene anche i seguenti file. Solo AndroidManifest.xml
è obbligatorio:
resources.arsc
: contiene le risorse compilate. Questo file contiene i contenuti XML di tutte le configurazioni della cartellares/values/
. Lo strumento di creazione del pacchetto estrae questi contenuti XML, li compila in formato binario e li archivia. Questi contenuti includono stringhe e stili di lingua, nonché percorsi a contenuti non inclusi direttamente nel fileresources.arsc
, come file di layout e immagini.classes.dex
: contiene le classi compilate nel formato di file DEX compreso dalla macchina virtuale Dalvik o ART.AndroidManifest.xml
: contiene il file manifest Android principale. Questo file elenca il nome, la versione, i diritti di accesso e i file di libreria a cui fa riferimento l'app. Il file utilizza il formato XML binario di Android.
Riduci il numero e le dimensioni delle risorse
Le dimensioni dell'APK influiscono sulla velocità di caricamento dell'app, sulla quantità di memoria utilizzata e sul consumo di energia. Puoi ridurre le dimensioni dell'APK diminuendo il numero e le dimensioni delle risorse che contiene. In particolare, puoi rimuovere le risorse che la tua app non utilizza più e puoi utilizzare oggetti Drawable
scalabili al posto dei file immagine. Questa sezione illustra questi metodi e altri modi per ridurre le
risorse nella tua app e diminuire le dimensioni complessive dell'APK.
Rimuovere le risorse inutilizzate
Lo strumento lint
, un analizzatore di codice statico
incluso in Android Studio, rileva le risorse nella cartella res/
a cui il tuo codice
non fa riferimento. Quando lo strumento lint
rileva una risorsa potenzialmente inutilizzata nel tuo progetto, stampa un messaggio come il seguente esempio:
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
Le librerie che aggiungi al codice potrebbero includere risorse inutilizzate. Gradle può rimuovere automaticamente
le risorse per tuo conto se attivi
shrinkResources
nel file
build.gradle.kts
della tua app.
Kotlin
android { // Other settings. buildTypes { getByName("release") { minifyEnabled = true shrinkResources = true proguardFiles(getDefaultProguardFile('proguard-android.txt'), "proguard-rules.pro") } } }
Groovy
android { // Other settings. buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
Per utilizzare shrinkResources
, attiva la riduzione del codice. Durante la procedura di build, R8 rimuove
innanzitutto il codice inutilizzato. Poi, il plug-in Android per Gradle rimuove le risorse non utilizzate.
Per ulteriori informazioni sulla riduzione del codice e delle risorse e su altri modi in cui Android Studio riduce le dimensioni degli APK, consulta Ridurre, offuscare e ottimizzare l'app.
Nel plug-in Android per Gradle 7.0 e versioni successive, puoi dichiarare le configurazioni supportate dalla tua app. Gradle trasmette queste informazioni al sistema di build utilizzando il
resourceConfigurations
flavor e l'opzione defaultConfig
. Il sistema di compilazione impedisce quindi la visualizzazione delle risorse
di altre configurazioni non supportate nell'APK, riducendone le dimensioni. Per ulteriori
informazioni su questa funzionalità, consulta
Rimuovere le risorse
alternative inutilizzate.
Ridurre al minimo l'utilizzo delle risorse delle librerie
Quando sviluppi un'app per Android, di solito utilizzi librerie esterne per migliorare l'usabilità e la versatilità dell'app. Ad esempio, puoi fare riferimento ad AndroidX per migliorare l'esperienza utente sui dispositivi precedenti oppure puoi utilizzare Google Play Services per recuperare le traduzioni automatiche del testo all'interno dell'app.
Se una libreria è progettata per un server o un computer, può includere molti oggetti e metodi che la tua app non richiede. Per includere solo le parti della libreria di cui la tua app ha bisogno, puoi modificare i file della libreria se la licenza ti consente di farlo. Puoi anche utilizzare una libreria alternativa ottimizzata per il mobile per aggiungere funzionalità specifiche alla tua app.
Decodifica delle immagini animate native
In Android 12 (livello API 31), l'API NDK
ImageDecoder
viene estesa per decodificare
tutti i frame e i dati di temporizzazione delle immagini che utilizzano i formati di file GIF animata e WebP animato.
Utilizza ImageDecoder
anziché librerie di terze parti per
ridurre ulteriormente le dimensioni dell'APK e usufruire di futuri
aggiornamenti relativi a sicurezza e prestazioni.
Per maggiori dettagli sull'API ImageDecoder
, consulta
API reference
e l'esempio
su GitHub.
Supporta solo densità specifiche
Android supporta diverse densità dello schermo, ad esempio:
ldpi
mdpi
tvdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
Sebbene Android supporti le densità precedenti, non è necessario esportare le risorse rasterizzate in ogni densità.
Se sai che solo una piccola percentuale dei tuoi utenti ha dispositivi con densità specifiche, valuta se devi raggruppare queste densità nella tua app. Se non includi risorse per una densità dello schermo specifica, Android ridimensiona automaticamente le risorse esistenti originariamente progettate per altre densità dello schermo.
Se la tua app ha bisogno solo di immagini scalate, puoi risparmiare ancora più spazio con una sola variante di
un'immagine in drawable-nodpi/
. Ti consigliamo di includere almeno una variante dell'immagine xxhdpi
nella tua app.
Per ulteriori informazioni sulle densità schermo, vedi Dimensioni e densità dello schermo.
Utilizzare oggetti disegnabili
Alcune immagini non richiedono una risorsa immagine statica. Il framework può disegnare dinamicamente l'immagine
in fase di runtime. Gli oggetti Drawable
o <shape>
in
XML possono occupare una quantità minima di spazio nell'APK. Inoltre, gli oggetti XML Drawable
producono immagini monocromatiche conformi alle linee guida di Material Design.
Riutilizzare le risorse
Puoi includere una risorsa separata per le variazioni di un'immagine, ad esempio versioni colorate, ombreggiate o ruotate della stessa immagine. Tuttavia, ti consigliamo di riutilizzare lo stesso insieme di risorse e di personalizzarle in base alle esigenze in fase di runtime.
Android fornisce diverse utilità per modificare il colore di una risorsa, utilizzando gli attributi
android:tint
e tintMode
.
Puoi anche omettere le risorse che sono solo un equivalente ruotato di un'altra risorsa. Il seguente snippet di codice fornisce un esempio di trasformazione di un "Mi piace" in un "Non mi piace" ruotando l'immagine di 180 gradi attorno al centro:
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_thumb_up" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="180" />
Rendering dal codice
Puoi anche ridurre le dimensioni dell'APK eseguendo il rendering procedurale delle immagini. Il rendering procedurale libera spazio perché non memorizzi più un file immagine nell'APK.
Comprimere i file PNG
Lo strumento aapt
può ottimizzare le risorse immagine inserite in res/drawable/
con compressione lossless durante il processo di compilazione. Ad esempio, lo strumento aapt
può convertire un PNG a colori reali che non richiede più di 256 colori in un PNG a 8 bit con una tavolozza di colori. In questo modo, l'immagine avrà la stessa qualità, ma occuperà meno spazio di memoria.
aapt
presenta le seguenti limitazioni:
- Lo strumento
aapt
non riduce le dimensioni dei file PNG contenuti nella cartellaasset/
. - I file immagine devono utilizzare 256 colori o meno per consentire allo strumento
aapt
di ottimizzarli. - Lo strumento
aapt
potrebbe gonfiare i file PNG già compressi. Per evitare questo problema, puoi utilizzare il flagisCrunchPngs
per disattivare questa procedura per i file PNG:
Kotlin
buildTypes.all { isCrunchPngs = false }
Groovy
buildTypes.all { isCrunchPngs = false }
Comprimere i file PNG e JPEG
Puoi ridurre le dimensioni dei file PNG senza perdere la qualità dell'immagine utilizzando strumenti come pngcrush, pngquant o zopflipng. Tutti questi strumenti possono ridurre le dimensioni dei file PNG mantenendo la qualità percettiva dell'immagine.
Lo strumento pngcrush
è particolarmente efficace. Questo strumento esamina i filtri PNG e
i parametri zlib (Deflate), utilizzando ogni combinazione di filtri e parametri per comprimere l'immagine.
Quindi, sceglie la configurazione che produce l'output compresso più piccolo.
Per comprimere i file JPEG, puoi utilizzare strumenti come packJPG e guetzli.
Utilizzare il formato di file WebP
Anziché utilizzare file PNG o JPEG, puoi utilizzare anche il formato WebP per le tue immagini. Il formato WebP offre compressione con perdita e trasparenza, come JPG e PNG, e può fornire una compressione migliore rispetto a JPEG o PNG.
Puoi convertire le immagini BMP, JPG, PNG o GIF statiche esistenti nel formato WebP utilizzando Android Studio. Per ulteriori informazioni, vedi Creare immagini WebP.
Utilizzare grafica vettoriale
Puoi utilizzare la grafica vettoriale per creare icone indipendenti dalla risoluzione e altri contenuti multimediali scalabili.
Puoi utilizzare queste immagini per ridurre notevolmente l'ingombro dell'APK. Le immagini vettoriali sono rappresentate in
Android come
oggetti VectorDrawable
. Con un oggetto VectorDrawable
, un file di 100 byte può generare un'immagine nitida
delle dimensioni dello schermo.
Tuttavia, il sistema impiega molto più tempo per eseguire il rendering di ogni
oggetto VectorDrawable
e le immagini più grandi impiegano ancora più tempo per essere visualizzate sullo schermo.
Pertanto, valuta la possibilità di utilizzare queste immagini vettoriali solo quando visualizzi immagini di piccole dimensioni.
Per ulteriori informazioni sull'utilizzo degli oggetti VectorDrawable
, consulta
Drawables.
Utilizzare la grafica vettoriale per le immagini animate
Non utilizzare
AnimationDrawable
per creare animazioni fotogramma per fotogramma, perché in questo modo è necessario includere un file bitmap
separato per ogni fotogramma dell'animazione, il che aumenta drasticamente le dimensioni dell'APK.
Utilizza invece
AnimatedVectorDrawableCompat
per creare
risorse grafiche
vettoriali animate.
Ridurre il codice nativo e Java
Puoi utilizzare i seguenti metodi per ridurre le dimensioni del codebase Java e nativo nella tua app.
Rimuovere il codice generato non necessario
Assicurati di comprendere l'impronta di qualsiasi codice generato automaticamente. Ad esempio, molti strumenti di protocol buffer generano un numero eccessivo di metodi e classi, che possono raddoppiare o triplicare le dimensioni dell'app.
Evitare le enumerazioni
Una singola enumerazione può aggiungere circa 1-1,4 KB al file classes.dex
della tua app. Queste
aggiunte possono accumularsi rapidamente per sistemi complessi o librerie condivise. Se possibile, valuta la possibilità di
utilizzare l'annotazione @IntDef
e la riduzione del codice
per rimuovere le enumerazioni e convertirle in numeri interi. Questa conversione del tipo conserva tutti i vantaggi
della sicurezza dei tipi degli enum.
Ridurre le dimensioni dei binari nativi
Se la tua app utilizza codice nativo e l'NDK Android, puoi anche ridurre le dimensioni della versione di rilascio ottimizzando il codice. Due tecniche utili sono la rimozione dei simboli di debug e la mancata estrazione delle librerie native.
Rimuovere i simboli di debug
L'utilizzo dei simboli di debug è utile se la tua app è in fase di sviluppo e richiede ancora il debug. Utilizza
lo strumento arm-eabi-strip
fornito in Android NDK per rimuovere i simboli di debug non necessari
dalle librerie native. Dopodiché, puoi compilare la build della release.
Evitare l'estrazione delle librerie native
Quando crei la versione di rilascio della tua app, inserisci i file .so
non compressi nell'APK impostando useLegacyPackaging
su false
nel file build.gradle.kts
dell'app. La disattivazione di questo flag impedisce
a PackageManager
di
copiare i file .so
dall'APK al file system durante l'installazione. Questo metodo rende
più piccoli gli aggiornamenti della tua app.
Mantenere più APK lean
Il tuo APK potrebbe contenere contenuti che gli utenti scaricano ma non utilizzano mai, come risorse linguistiche aggiuntive o per densità dello schermo. Per garantire un download minimo per i tuoi utenti, carica la tua app su Google Play utilizzando Android App Bundle. Il caricamento degli app bundle consente a Google Play di generare e pubblicare APK ottimizzati per la configurazione del dispositivo di ogni utente, in modo che scarichino solo il codice e le risorse necessari per eseguire la tua app. Non devi creare, firmare e gestire più APK per supportare dispositivi diversi e gli utenti ottengono download più piccoli e ottimizzati.
Se non pubblichi la tua app su Google Play, puoi segmentarla in diversi APK, differenziati in base a fattori quali le dimensioni dello schermo o il supporto delle texture della GPU.
Quando un utente scarica la tua app, il suo dispositivo riceve l'APK corretto in base alle funzionalità e alle impostazioni del dispositivo. In questo modo, i dispositivi non ricevono asset per funzionalità che non
hanno. Ad esempio, se un utente ha un dispositivo hdpi
, non ha bisogno di risorse xxxhdpi
che potresti includere per i dispositivi con display ad alta densità.
Per ulteriori informazioni, vedi Creare più APK e Supporto di più APK.