Android ridurre dimensione apk
Nella fase di sviluppo è molto importante non trascurare la dimensione di una applicazione.
Infatti la dimensione si riflette sulla velocità di caricamento, la memoria che esso usa, e la batteria che consuma.
Oltre queste motivazioni, essa potrebbe determinare la longevità e l’acquisizione, da parte di nuovi utenti, dell’applicazione.
Infatti, spesso l’utente ha necessità di disinstallare qualche applicazione, e la scelta spesso ricade sulle applicazioni poco usate e con dimensioni elevate (è un valore soggettivo).
Ovviamente questo ragionamento vale anche per i nuovi utenti, che potrebbero cambiare idea basandosi sulla dimensione dell’applicazione.

In questo articolo vedremo come ridurre la dimensione dell’applicazione con pochi e semplici passaggi.
Nella documentazione Android viene consigliato di effettuare questi passaggi:
- Reduce resource count and size
- Reduce native and Java code
- Maintain multiple lean APKs
Ma prima di effettuare tali passaggi, è bene andare ad individuare quali sono i componenti che compongono l’apk.
Per far ciò Android studio, a partire dalla versione 2.2, mette a disposizione APK Analyzer un tool per analizzare gli APK.
Questo tool (accessibile attravero il menu item: Build -> Analyze APK) permette di visualizzare il contenuto dell’ APK e dare una panoramica su quali file stanno occupando maggior spazio.

Dall’output si nota che ciò che occupa più dimensione sono 2 cartelle e dei file classes.dex.
- classes.dex sono i file dex i quali contengono tutti i byte code del codice java. In questo caso sono vari file, vedremo dopo il motivo.
- res questa cartella include tutte le immagini, icone raw files, menu files e layout.
- lib questa cartella include tutti i files contenuti nelle librerie di terze parti
Quindi il nostro obiettivo è andare a diminuire la dimensione di questi file e cartelle e ciò equivale a seguire gli step indicati nella documentazione android di cui abbiamo parlato in precedenza.
Reduce native and Java code:
I files classes.dex contengono tutto il codice java. Effettuando la build dell’applicazione, gradle converte tutti i file .class in un singolo file classes.dex.
Questo file ha però una limitazione nel numero dei metodi pari circa a 64k , nel caso si ecceda tale metodo occorre abilitare il multidexing (multiDexEnabled), che splitterà i vari metodi in diversi file.
Per questo step invito a leggere i consigli indicati nella documentazione android.
Ciò che si può fare in aggiunta a quanto indicato nella documentazione, è utilizzare Proguard abilitando l’opzione minifyEnabled, in modo da rimuovere tutti i metodi non utilizzati, in questo modo si diminuiscono anche i file classes.dex. Proguard viene utilizzato anche per offuscare il codice.
Reduce resource count and size:
La cartella res, contiene tutte le immagini, raw files e XML.
I passi da effettuare sono:
- Rimuovere le risorse non utilizzate, per far ciò possiamo avvalerci del tool
lint, incluso in Android Studio, che rileva e segnala (non rimuove automaticamente) tutte le risorse nella cartellares/che non sono referenziate nel codice.
E’ bene sottolineare chelintnon effettua la scansione nella cartellaassets/, la quale è referenziata attraverso la reflection, e nelle librerie terze utilizzate.
Le librerie terze aggiunte, potrebbero includere risorse inutilizzate, gradle può automaticamente rimuoverle abilitandoshrinkResources.
Quindi durante il processo di build, ProGuard rimuove il codice non usato ma lascia le risorse inusate, mentre gradle rimuove le risorse non utilizzate.
- riutilizzare le risorse e modificarle a runtime.
- ridurre la dimensione delle immagini. Per far ciò a partire da Android Studio 2.3, e se l’applicazione ha come versione minima 18, è possibile usare il formato webp invece di png e jpg. Tale formato è nativamente supportato in android, quindi possono essere utilizzati senza dover apportare modifiche nei layout.
Convertire immagini in webp è semplicissimo, puoi trovare maggiori info qui, ma darò una rapida panoramica:
Selezionando la cartella drawable o mipmap o un singolo file, premendo il tasto destro e selezionando convert to webp, apparirà il seguente dialog:

E premendo ok avverrà la conversione, del singolo file oppure di tutti i file uno alla volta. Nel caso l’immagine webp ha una dimensione maggiore all’originale allora Android Studio non effettuerà la conversione.
- usa il formato vettoriale svg, invece dei png, per le icone. Questo formato è indipendente dalla risoluzione, quindi non ci si deve preoccupare dei differenti DPI dei vari devices, e ciò si traduce anche in una riduzione della dimensione dell’apk.
Per aggiungere icone vettoriali si può utilizzare il tool presente in android studio. Per avviarlo basta premere sulla cartella res il tasto destro, quindi cliccare su new e poi su Vector Asset:

Il consiglio è generare le icone usando come colore il nero e poi utilizzare la proprietà android:tint per modificare il colore.
Per la retrocompatibilità, a partire dalla SupportLibrary 32.2 si può usare la proprietà app:srcCompat delle ImageView invece di android:src.
Reduce lib:
La libreria che occupa spazio è realm, in un post pubblicato sul sito di realm viene spiegato come risolvere tale problema e consiste nel seguire ciò che viene indicato anche nella documentazione android, ossia creare diversi file apk.
Conclusioni:
Nel mio caso particolare ho eseguito prima la riduzione delle risorse (eliminazione risorse non utilizzate e formato webp):

Dopo di che ho abilitato Proguard:

Ottenendo in fine una dimensione totale pari a 8.3MB, invece di 17.9MB, inoltre grazie a Proguard il numero dei metodi è diminuito da oltre 65k, che richiedeva l’abilitazione del multidex, a circa 50k. Quindi una diminuzione pari circa al 54%.