Utilizzare al meglio l’analizzatore APK

Wojtek Kaliciński

Follow

23 novembre, 2016 – 6 min read

Una delle mie aggiunte recenti preferite ad Android Studio è l’APK Analyzer, che puoi trovare nel menu in alto sotto Build → Analyze APK.

Pro-tip: puoi anche trascinare i file APK nell’editor per aprirli

APK Analyzer ti permette di aprire e ispezionare il contenuto di qualsiasi file APK che hai sul tuo computer, sia costruito dal tuo progetto locale di Android Studio o acquisito dal tuo build server o altro repository di artefatti. Non deve essere costruito da qualsiasi progetto che hai aperto in Android Studio e non hai bisogno del codice sorgente per quel particolare APK.

Nota: APK Analyzer funziona meglio con le build di rilascio. Se hai bisogno di analizzare una build di debug della tua app, assicurati di usare un APK che non sia strumentato per l’Instant Run. Per ottenerlo, puoi usare il comando Build → Build APK. Puoi vedere se hai aperto un APK strumentato per Instant Run controllando la presenza di un file instant-run.zip all’interno dell’archivio.

Utilizzare l’analizzatore APK è un ottimo modo per curiosare tra i file APK e conoscere la loro struttura, verificare il contenuto del file prima del rilascio o eseguire il debug di alcuni problemi comuni, tra cui la dimensione APK e i problemi DEX.

L’analizzatore APK può darti un sacco di informazioni utili e utilizzabili sulle dimensioni delle app. Nella parte superiore dello schermo, puoi vedere la Raw File Size che è solo la dimensione dell’APK sul disco. La dimensione del download mostra una stima di quanti dati verranno utilizzati per scaricare la tua app tenendo conto della compressione applicata dal Play Store.

L’elenco di file e cartelle è ordinato per dimensione totale in ordine decrescente. Questo lo rende ottimo per identificare i frutti a portata di mano dell’ottimizzazione delle dimensioni dell’APK. Ogni volta che scendi in una cartella, puoi vedere le risorse e le altre entità che occupano più spazio nel tuo APK.

Risorse ordinate in ordine decrescente in base alla dimensione

In questo esempio, esaminando un APK per possibili riduzioni di dimensioni, sono stato in grado di notare immediatamente che un’animazione PNG a 3 fotogrammi è la singola cosa più grande nelle nostre risorse disegnabili, con un peso di 1.5MB, e questo solo per la densità xxhdpi!

Siccome queste immagini sembrano candidati perfetti per la memorizzazione come vettori, abbiamo trovato i file di origine per l’artwork e li abbiamo importati come VectorDrawables utilizzando il nuovo supporto PSD nello strumento di importazione Vector Asset in Android Studio 2.2.

Passando attraverso lo stesso processo per l’altra animazione rimanente (instruction_touch_*.png) e rimuovendo questi file PNG in tutte le densità, siamo stati in grado di risparmiare oltre 5MB. Per mantenere la retrocompatibilità abbiamo usato VectorDrawableCompat dalla libreria di supporto.

Guardando altre cartelle di risorse, è stato facile individuare alcuni file WAV non compressi che potevano essere convertiti in OGG, il che significava un risparmio ancora maggiore senza toccare una riga di codice.

Cercando altre cartelle nell’APK

La prossima nella lista delle cose da controllare era la cartella lib/, che contiene librerie native per le tre ABI che supportiamo.

Si è deciso di usare il supporto APK splits nella nostra build Gradle per creare versioni separate dell’app per ogni ABI.

Ho dato un’occhiata veloce all’AndroidManifest.xml e ho notato che <application> manca l’attributo android:extractNativeLibs. Impostare questo attributo su false può far risparmiare un po’ di spazio sul dispositivo in quanto impedisce di copiare le librerie native dall’APK al filesystem. L’unico requisito è che i file siano allineati alla pagina e memorizzati non compressi all’interno dell’APK, il che è supportato dal nuovo packager nel plugin Android Gradle versione 2.2.0+.

L’AndroidManifest.xml completo come visto in APK Analyzer

Dopo aver fatto queste modifiche, ero curioso di vedere come la nuova versione dell’app si confronta con la precedente. Per farlo, ho controllato il sorgente dal commit git con cui ho iniziato, ho compilato l’APK e l’ho salvato in un’altra cartella. Ho poi usato la funzione Compare with… per vedere una ripartizione delle differenze di dimensione tra la vecchia e la nuova build.

Confronto APK – accedi tramite il pulsante in alto a destra

Abbiamo fatto molti progressi sulle risorse e sulle librerie native, risparmiando un totale di 17MB con pochissimi cambiamenti nell’app. Tuttavia, posso vedere che le dimensioni del nostro DEX sono regredite, con il classes2.dex che è cresciuto di 400KB.

Debugare i problemi del DEX

In questo caso, la differenza è venuta dall’aggiornamento delle nostre dipendenze a versioni più recenti e dall’aggiunta di nuove librerie. Proguard e Multidex erano già abilitati per le nostre build, quindi non c’è molto che si possa fare sulla nostra dimensione DEX. Tuttavia, APK analyzer è un ottimo strumento per il debug di qualsiasi problema con questa configurazione, specialmente quando si abilita Multidex o Proguard per il proprio progetto per la prima volta.

Esplorando il contenuto delle classi.dex

Quando cliccate su qualsiasi file DEX, vedrete un riassunto di quante classi e metodi definisce, e quanti riferimenti totali contiene (sono i riferimenti che contano nel limite di 64K in un singolo file DEX). In questa schermata di esempio, l’applicazione sta per raggiungere il limite, il che significa che avrà bisogno di MultiDex per dividere le classi in file separati nel prossimo futuro.

Puoi approfondire i pacchetti per vedere quali stanno utilizzando tutti i riferimenti. In questo caso, possiamo vedere che la libreria Support e Google Play Services sono le cause principali di questa situazione:

Conteggio dei riferimenti per pacchetto

Una volta attivato MultiDex e compilata la tua app, noterai un secondo file classes2.dex (e possibilmente classes3.dex, e così via). La soluzione MultiDex nel plugin gradle di Android capisce quali classi sono necessarie per avviare la tua app e le mette nel file primario classes.dex, ma nel raro caso in cui non funzioni e ottieni una ClassNotFoundException, puoi usare APK Analyzer per ispezionare i file DEX, e quindi forzare le classi mancanti ad essere messe nel file DEX primario.

Incontrerai problemi simili quando abiliti Proguard e usi classi o metodi per riflessione o da layout XML. L’APK Analyzer può aiutarvi a verificare che la vostra configurazione di Proguard sia corretta, permettendovi di controllare facilmente se i metodi e le classi di cui avete bisogno sono presenti nell’APK e se sono stati rinominati (offuscati). Puoi anche assicurarti che le classi che vuoi eliminare siano effettivamente rimosse e non occupino il tuo prezioso numero di metodi di riferimento.

Siamo curiosi di sentire quali altri usi trovi per APK Analyzer e quali altre caratteristiche vorresti vedere integrate nello strumento!

Lascia un commento