"The code is joy and passion but it has a high degree of suffering"

Tips and tricks: velocizzare gradle e ridurre gli apk parte 2

Posted by on ott 16, 2015 in Tutte | 0 comments

Tips and tricks: velocizzare gradle e ridurre gli apk parte 2

Nella prima parte dell’ articolo vi ho parlato di proguard, un tool che oltre ad “obscurare” il codice può ridurre un apk anche del 35% o più. In questa seconda parte vi elencherò altre tecniche per mettere a dieta l’ apk.
Da pochi giorni Google ha aumentato il peso massimo di un apk per il Play Store portandolo a  100mb, ma è importante che la nostra applicazione non sia molto pesante perchè può essere un deterrente al download e ai successivi aggiornamenti.

Lint

Uno strumento che ci permette di ottimizzare il codice è senza dubbio Lint. Lint è un tool che analizza il codice sia java che xml e crea un report con:

  • risorse non utilizzate
  • tag xml non utilizzati e non chiusi correttamente
  • variabili non utilizzate
  • import di package non utilizzati

L’ elenco è molto vasto e soprattutto l’ individuazione delle risorse non utilizzate ci permette di risparmiare kb inutili. Il sistema di building di Android non prevede il filtro delle risorse non utilizzate. Se in un nostro progetto inseriamo in una delle cartelle drawable o in asset un’ immagine di 10 mb anche se nè da xml nè da codice la utilizziamo  il file  apk conterrà ugualmente l’ immagine facendo aumentare il peso finale.
E’ normale che durante lo sviluppo il designer (o il project manager) cambi idea su icone, layout  e spesso non si ha il tempo ne l’ opportunità di cancellare le vecchie risorse. Font, icone, png di background, layout, tutte risorse che incrementano i kb della release finale.

Lint è facile da usare. E’ già attivo durante lo sviluppo, Android Studio per esempio ci mostra sempre se una variabile o una classe non sono utilizzate. Per avere una visione di insieme possiamo utilizzare Lint da interfaccia: Analyze-> Inspect Code

inspect

Nella successiva schermata possiamo scegliere il modulo app cosi che Lint analizzi solo il nostro codice e non il codice di altri moduli, librerie.

moduloapp

Il risultato è visibile in basso e basta cliccare sulla voce per aprire il file e modificare come consiglia Lint.

report

Possiamo utilizzare Lint anche da riga di comando se preferite:

E’ possibile creare anche un report in formato html:

Gradle shrinking

Lint è utile ma crea degli alert e un report, poi è compito dello sviluppatore sistemare secondo indicazione o eliminare le risorse non utilizzate.
Gradle  permette, con poche istruzioni, di ridurre il nostro apk in automatico. Aggiungiamo e settiamo a true la proprietà shrinkResources

Con una sola riga, in automatico, saranno eliminate le risorse non utilizzate. La proprietà shrinkResources richiede soltanto che proguard sia attivato con minifyEnabled true
Uno dei problemi dell’ eliminazione delle risorse inutilizzate in automatico è che il tool potrebbe rimuovere risorse che vengono usate in maniera dinamica. Per prevenire questo possiamo definire un’ eccezione. Creiamo un file xml nella cartella res/raw. Il nome del file deve essere keep.xml. Il contenuto:

Quando usate proguard e/o shrinkResources è importante ricontrollare il funzionamento dell’ applicazione. I tool automatici fanno miracoli ma è sempre meglio controllare e testare prima della pubblicazione sul play store.

Possiamo ridurre il nostro apk anche “manualmente” cioè configurando Gradle in modo tale da eliminare quello che non ci serve o che non ci serve per quella release.

Per esempio possiamo mantenere solo alcune lingue o solo alcune risoluzioni:

In questo caso se avessimo più lingue, magari lingue asiatiche come il cinese, con resConfigs manteniamo solo le lingue inglese ed italiano. Anche per le varianti di risoluzioni/densità possiamo mantenerne solo alcune.

Un accorgimento semplice ma molto utile può essere usato nelle dipendenze. Per esempio invece di  inserire la dipendenza di tutto il  play service:

 importiamo solo i servizi che ci servono; per esempio

L’ import delle dipendenze è  selettivo; importeremo solo maps e wearable: cosi da escludere gli altri servizi di google non necessari al nostro progetto.

Non esiste la ricetta magica ma con un po di configurazioni, ottimizzazioni e prove possiamo ridurre il peso dell’ apk. Oltre a Proguard, Lint, Gradle è importante utilizzare immagini già ottimizzate e immagini in formato png. Utilizzate anche le 9-patches per sfondi e pulsanti, riducono di tanto l’ utilizzo di grosse png “ripetitive”.

 

Read More

Tips and tricks: velocizzare gradle e ridurre gli apk parte 1

Posted by on ott 14, 2015 in Tutte | 3 comments

Tips and tricks: velocizzare gradle e ridurre gli apk parte 1

Riprendo a scrivere  dopo un po di assenza, il lavoro e la famiglia mi tengono lontano dal blog purtroppo.
Ho scritto un articolo sul Databinding per cosenonjaviste nel frattempo: http://cosenonjaviste.it/android-data-binding/

Oggi non voglio parlarvi di codice ma di alcuni aspetti che spesso vengono trascurati: compilazione, velocizzare il processo di build e ridurre il peso di un apk.

Velocizzare gradle

Gradle ha cambiato totalmente il processo di building su Android, è molto configurabile e potente  ma a volte il processo di compilazione e building  può diventare lento. Possiamo migliorare la velocità con poche modifiche.

Modifichiamo il file gradle.properties presente nella root del progetto (nb: root progetto non root modulo app).
Aggiungiamo queste righe di codice:

La riga ord.gradle.parallel è utile solo se il vostro progetto ha diversi (anche solo 2) moduli perchè con il parametro settato a true i moduli saranno configurati e buildati in parallelo rendendo più veloce il processo. Il demone Gradle è un processo in background che è inizializzato la prima volta che si effettua un sync del progetto e successivamente riusato nelle successive build.
Teoricamente Android Studio di default lo configura a true e infatti è la situazione abituale: la prima volta che lanciate l’ applicazione in debug  il processo è lento e le successive volte è molto più veloce.
La terza riga org.gradle.configureondemand diventa indispensabile se la vostra applicazione utilizza moduli complessi e soprattutto se sono tanti . Permette di “skippare”, ignorare task, configurazioni dei moduli  che non vengono modificati tra diverse build.
Se tra una build e l’ altra non modificate le librerie e/o i moduli, Gradle non eseguirà nuovamente le procedure necessarie alla build per quei moduli. Si occuperà solo del modulo app.

Un metodo per essere sicuri che verrà preso in considerazione solo il modulo app e ignorati gli altri moduli è l’ utilizzo di questa istruzione dalla riga di comando:

Un’ altra riga che potreste aggiungere al file gradle.properties  è la riga che permette di inviare parametri alla Java Virtual Machine. La proprietà da cambiare è jvmargs:

Xms serve per configurare la memoria iniziale mentre Xmx configura il massimo della memoria da utilizzare. I valori possono cambiare e dipende dal vostro hardware e dalla macchina che utilizzate per lo sviluppo. Fate delle prove per ottenere la configurazione ideale.

Aggiungendo poche righe la velocità di building migliorerà sensibilmente. Per ogni progetto è necessario modificare il file gradle.properties ma è possibile anche rendere le modifiche che ho elencato anche  di default per tutti i nuovi progetti.

Create,se non esiste, o modificate il file gradle.properties nella cartella principale di gradle che si trova:

Per i  Mac:
/Users/USER_NAME/.gradle/gradle.properties

Per Linux:
/home/USER_NAME/.gradle/gradle.properties

Per Windows:
C:\Users\USER_NAME\.gradle\gradle.properties

E’  possibile velocizzare gradle utilizzando dexOptions. Aggiungete nel file build.gradle  dentro android {…}

Fate attenzione ad incremental dexing potrebbe far fallire la compilazione. La raccomandazione del team di sviluppo di Android Studio è di provare e verificare.

Gradle mette a disposizione un report per profilare le build cosi da rendersi conto delle tempistiche dei vari task e processi. Per creare il report da riga di comando nella root del progetto scriviamo

Trovate il report, una pagina html, in {root progetto}/build/reports/profile.

 

profile

 

Proguard

Proguard non è una novità su Android: è un tool java presente nel Sdk di Android che non solo riduce il peso dell’ apk ma ottimizza , esegue un preverifica del codice in compile time e agisce come obscurator cioè rende il codice illegibile ai decompiler. Rinomina le classi e le proprietà cosi da rendere più complicato il reverse engineer.
Abilitare il tool è semplice: dobbiamo settare a true la proprietà minifyEnabled presente nelle impostazioni di default del plugin Android.

Modifichiamo il file build.gradle presente nella root del nostro modulo app:

E’ necessario solo questo parametro e proguard si attiverà durante la fase di building delle release. Dipende molto dal progetto ma spesso il peso del  file apk si riduce di un 35-50% .
proguard-android.txt è un file presente nel Sdk di android  ../android-sdks/tools/proguard ed è un elenco di tutte le eccezioni, impostazioni del tool proguard.
Android Studio aggiunge un altro file proguard-reles.pro che si trova nella root del vostro modulo app. Il file contiene solo commenti: inserite le vostre personalizzazioni in questo file. Spesso durante la fase di building con proguard attivato vengono rilevati errori e la build non viene creata. Leggete bene i log e riuscirete a sistemare ogni cosa.
Io per esempio in alcuni miei progetti ho dovuto inserire:

E’ possibile aggiungere personalizzazioni di proguard anche solo per un flavor

Proguard è uno strumento potente ma fate attenzione, è necessario ritestare l’ applicazione perchè è possibile che proguard elimini dei metodi o delle risorse utili . Basta un veloce test per rendersi conto se tutto va bene.

Per approfondire http://developer.android.com/tools/help/proguard.html

Nella seconda parte di questo articolo vi mostrerò alcune tecniche per ridurre il peso dell’ apk finale.

 

Read More

The world of RecyclerView – parte 2

Posted by on mar 25, 2015 in Tutte | 0 comments

The world of RecyclerView – parte 2

Nella prima parte di questa serie di articoli dedicati al mondo delle RecyclerView ho descritto il nuovo approccio alle liste dal punto di vista teorico,  in questa seconta parte vi illustrerò il  codice dell’ esempio allegato.

L’ esempio visualizza una lista di nomi di paesi.

Per prima cosa importiamo le dipendenze. Nel file build.gradle del modulo app inseriamo:

 

Il layout dell’ Activity: in questo esempio ho usato anche  la nuova Toolbar.

activity_main.xml

Il layout di un singolo item: una semplice TextView.

country_item.xml

Nell’ activity principale nel metodo onCreate ho scritto il codice per utilizzare la RecyclerView.

Nella prima riga creo un ArrayList<String> prendendo i dati da un array-string dalle risorse string, poi recupero il riferimento della RecyclerView.
La RecyclerView utilizza un’ istanza di RecyclerView.Adapter:  ho creato l’ adapter CountriesAdapater che vedremo dopo.
Utilizziamo il costruttore per passare la lista dei Model all’ adapter.

Come descritto nella prima parte della serie, le RecyclerView non si occupano della visualizzazione delle view,  questo compito adesso è gestito da un layout manager.
Le tipologie di layout manager che possiamo usare di default sono 3:

  • LinearLayoutManager: crea una lista verticale o orizontale.
  • GridLayoutManager: crea una griglia a blocchi
  • StaggeredGridLayoutManager: crea una griglia a blocchi non ordinati

E’ possibile anche creare dei layout manager personalizzati.

Nell’ esempio ho utilizzato un’ istanza di LinearLayoutManager che di default usa l’ orientamento verticale come nelle ListView.
La riga 7 può essere anche omessa, per le animazioni useremo un’ istanza della classe RecyclerView.ItemAnimator; vedremo nella terza parte di questa serie come personalizzare le animazioni.
Come nelle ListView  passiamo alla Recyclerview l’ adapter.
In  6-7 righe troviamo tutto il codice che ci serve per creare e configurare una lista.

E’ arrivato il momento di guardare con attenzione il nuovo adapter.
L’ adapter che utilizza la RecyclerView non estende più un BaseAdapter o un ArrayAdapter<T> ma è  una sottoclasse del RecyclerView.Adapter con il parametro generics del nuovo ViewHolder: in questo caso MyViewHolder che estende RecyclerView.ViewHolder

Il team di sviluppo Android  ha sempre consigliato l’ implementazione del pattern ViewHolder per fare cache delle view(e rendere efficienti le liste):  adesso ha creato una sua implementazione.(Era ora !! :) )

Ecco il codice:

I metodi più importanti dell’ adapter sono due:  onCreateViewHolderonBindViewHolder

Il metodo onCreateViewHolder esegue l’ inflate del layout (riga 14) e crea l’ istanza di MyViewHolder .
MyViewHolder estende RecyclerView.ViewHolder e si occupa di recuperare le view e creare la cache.
Il metodo onBindViewHolder gestisce le varie view che fanno parte del layout, in questo caso utilizza la TextView  mCountryText per scrivere il nome del paese (riga 21).

Per quanto riguarda la creazione della lista è tutto, Google ha semplificato il più possibile.

Ecco la nostra lista:

List Vertical

Lo schema è semplice: RecyclerView+LinearLayoutManager+Adapter (Model)

RecyclerView Schema

Nell’ esempio che vi ho allegato nella prima parte  e che vi riallego anche in questa, ho aggiunto la possibilità di cambiare in runtime il tipo di layout manager per farvi rendere conto della flessibilità ed estendibilità delle RecyclerView.

Attraverso le opzioni del menu settiamo un diverso layout manager .

Al tap del menu  grid creo un GridLayoutManager che visualizza la lista sotto forma di griglia (riga 4).
Ho aggiunto anche l’ opzione setSpanSizeLookup che determina  lo spazio di ogni item.

Ecco il risultato:

GridLayout

Al tap del menu list cambio l’ orientamento del LinearLayoutManager da verticale ad orizzontale e viceversa (righe 25 e 30).

Ecco il risultato:

List Horizontal

Con poche righe di codice possiamo cambiare totalemente la tipologia di visualizzazione delle nostre liste.

Le RecyclerView hanno un potenziale interessante e penso che Google ha l’ interesse a migliorarle (vedremo al Google I/O 2015).

E’ tutto, alla prossima puntata.

RecyclerViewExample source in GitHub

 

 

 

 

Read More

The world of RecyclerView – parte 1

Posted by on mar 23, 2015 in Android, RecyclerView | 0 comments

The world of RecyclerView – parte 1

Il  titolo di questa serie di articoli riprende il titolo di una delle più interessanti sessioni del Google I/O del 2010: The world of ListView : la serie invece tratterà  delle RecyclerView.
In quel talk  Romain Guy e Adam Powell spiegavano il mondo delle ListView: uno dei widget più usati e indispensabili nello sviluppo Android.
Il mondo delle RecyclerView è iniziato al Google I/O 2014 con Android 5.0 L chiamato dopo Android Lollipop.
Le Recyclerview e le ListView hanno molto in comune: la visualizzazione di elementi dello stesso tipo.
Si suppone che le recyclerview sostituiranno le listview.

La Recylerview è più avanzata,  flessibile e  veloce  nella gestione di grandi liste di dati. Quando l’ utente scorre verso l’ alto o verso il basso entra in gioco il riciclo degli elementi non più visualizzati: questo riciclo o riutilizzo delle view rende le  recylerview molto efficenti.
Il concetto appare molto simile alle ListView ma con un approcio diverso.
Mentre nelle Listview tutto è collegato: base dati, layout, immagini, componenti,animazioni; nelle recylerview non c’è questo stretto legame: la recyclerview non si preoccupa dove posizionare  gli elementi, nè delle immagini o  layout ma si preoccupa soprattutto del riciclo o riutilizzo delle view e rendere tutto più veloce.
Uno dei benefici di questo diverso approcio  è la possibilità di cambiare (in runtime) tipo di visualizzazione: da visualizzazione a lista verticale a lista orizzontale, da vista a card a vista custom. Vedremo in seguito qualche esempio.
Per la visualizzazione, i layout, la gestione dei  dati la recyclerview delega questi compiti alle sotto classi:

RecyclerView.Adapter
Simile all’ adapter che conosciamo si occupa di ricevere i dati e di creare le view.
Non  utilizzeremo  più ArrayAdapter<Model> ma RecyclerView.Adapter<ReclyclerView.ViewHolder>

RecyclerView.ViewHolder
Crea una cache delle view che servono alla creazione della lista.

RecyclerView.LayoutManager
Si occupa di posizionare le view e di determinare il tipo di visualizzazione.
La libreria mette a disposizione 3 differenti layout manager: LinearLayoutManagerGridLayoutManager,StaggeredGridLayoutManager

RecyclerView.ItemDecoration
Modifica l’ aspetto grafico degli item.

RecyclerView.ItemAnimator
Gestisce le animazioni. In genere le 3 principali azioni: adding, removing and moving

Queste sono le classi che permettono quella flessibilità di cui ho parlato prima.
Le recyclerview sono state sviluppate con lo scopo  di migliorare l ‘ estendibilità (extensibility).
Per cambiare totalmente visualizzazione scegliamo uno dei 3  LayoutManager o uno custom, per avere più  animazioni  personalizziamo  ItemAnimator,  per cambiare  l’ aspetto degli item usiamo ItemDecoration.

Merita attenzione la classe ViewHolder. Il pattern viewholder è sempre stato raccomandato dal team di google per rendere efficente la listview, e nella recylcerview (in ritardo secondo me) ha una vera e propria implementazione e ha un ruolo più importante.

Dimenticavo che possiamo usare le recyclerview anche nelle precedenti versioni di Android perchè sono state aggiunte alle librerie support.
Per Android Studio la dipendenza è:

Nella seconda parte della serie di articoli dedicati alle recyclerview spiegherò un esempio basilare e nei successivi articoli vedremo qualche esempio di personalizzazione e animazione.
Edit: aggiungo il link del primo esempio: RecyclerViewExample

Read More