Android Programmazione avanzata - CAT@logo CNR

Pagina creata da Caterina Albano
 
CONTINUA A LEGGERE
Android Programmazione avanzata - CAT@logo CNR
Fabio Collini
               Matteo Bonifazi, Alessandro Martellucci, Stefano Sanna

     Android    Programmazione avanzata

                                                                                        NUO
                                                                               IZIONE
                                                                             ED
                                                                                        BE

                                                                        2a
                                                                                 LLER
                                                                          ES TSE
                                                                        B

Sviluppo multidevice >>
Android Wear, Chromecast, Bluetooth Low Energy >>
Programmazione funzionale con RxJava >>
Testing e qualità del codice >>
Android Programmazione avanzata - CAT@logo CNR
Android Programmazione avanzata - CAT@logo CNR
Android
Programmazione avanzata
                   Seconda edizione

                    Fabio Collini
 Matteo Bonifazi, Alessandro Martellucci, Stefano Sanna
Android Programmazione avanzata - CAT@logo CNR
Android | Programmazione avanzata
Seconda edizione

Autori: Fabio Collini, Matteo Bonifazi, Alessandro Martellucci, Stefano Sanna

Collana:

Editor in Chief: Marco Aleotti
Progetto grafico: Roberta Venturieri
Immagine di copertina: © scanrail | Thinkstock

© 2015 Edizioni Lswr* – Tutti i diritti riservati
ISBN: 978-88-6895-071-2

I diritti di traduzione, di memorizzazione elettronica, di riproduzione e adattamento totale o parziale con qualsiasi mezzo (com-
presi i microfilm e le copie fotostatiche), sono riservati per tutti i Paesi. Le fotocopie per uso personale del lettore possono essere
effettuate nei limiti del 15% di ciascun volume dietro pagamento alla SIAE del compenso previsto dall’art. 68, commi 4 e 5, della
legge 22 aprile 1941 n. 633.
Le fotocopie effettuate per finalità di carattere professionale, economico o commerciale o comunque per uso diverso da
quello personale possono essere effettuate a seguito di specifica autorizzazione rilasciata da CLEARedi, Centro Licenze e
Autorizzazioni per le Riproduzioni Editoriali, Corso di Porta Romana 108, 20122 Milano, e-mail autorizzazioni@clearedi.org
e sito web www.clearedi.org.
La presente pubblicazione contiene le opinioni dell’autore e ha lo scopo di fornire informazioni precise e accurate. L’elaborazione
dei testi, anche se curata con scrupolosa attenzione, non può comportare specifiche responsabilità in capo all’autore e/o all’edi-
tore per eventuali errori o inesattezze.
L’Editore ha compiuto ogni sforzo per ottenere e citare le fonti esatte delle illustrazioni. Qualora in qualche caso non fosse riuscito
a reperire gli aventi diritto è a disposizione per rimediare a eventuali involontarie omissioni o errori nei riferimenti citati.
Tutti i marchi registrati citati appartengono ai legittimi proprietari.

Via G. Spadolini, 7
20141 Milano (MI)
Tel. 02 881841
www.edizionilswr.it

Printed in Italy
Finito di stampare nel mese di giugno 2015 presso “Rotolito Lombarda” S.p.A., Pioltello (MI)

(*) Edizioni Lswr è un marchio di La Tribuna Srl. La Tribuna Srl fa parte di                                .
Sommario
PREFAZIONE............................................................................................................... 9
INTRODUZIONE........................................................................................................11
1.     ACTIVITY E TASK IN BACKGROUND di Fabio Collini.................................17
       Ciclo di vita di una Activity.......................................................................................................17
       Gestione dei metodi di callback comuni a più Activity.................................................... 18
       Flusso delle callback del ciclo di vita di una Actvity..........................................................22
       Salvataggio dello stato di una Activity.................................................................................23
       Generazione automatica delle implementazioni
       di Parcelable................................................................................................................................26
       Tipi di dati da salvare in una Activity....................................................................................28
       UI Thread e concorrenza..........................................................................................................29
       Tipologie di task in background..............................................................................................33
       AsyncTask e Loader...................................................................................................................34
       IntentService e LocalBroadcastManager.............................................................................35
       EventBus ed Executor................................................................................................................ 41

2.     PROGRAMMAZIONE FUNZIONALE di Fabio Collini.................................47
       Lambda expression e method reference............................................................................. 48
       Retrolambda.................................................................................................................................51
       Linguaggi alternativi a Java su Android................................................................................52
       Manipolazione di dati con gli Stream di Java 8..................................................................53
       RxJava...........................................................................................................................................57
       Flussi di dati asincroni................................................................................................................61
       Gestione delle Subscription.................................................................................................... 66
       Gestione degli errori................................................................................................................. 68
       Chiamate a servizi REST con Retrofit.....................................................................................71
       Combinare più flussi di dati con RxJava...............................................................................73
       Hot e cold Observable............................................................................................................. 80
       Manipolazione di flussi di dati............................................................................................... 84
       Utilizzo dei Subject................................................................................................................... 86
       Eventi della UI con RxJava........................................................................................................92
       Gestione dei nested Observable........................................................................................... 94
       Task in background collegati al ciclo di vita di una Activity........................................... 96

                                                                                                                                                      5
Android | Programmazione avanzata

3.   GRAFICA E INTERFACCIA UTENTE di Fabio Collini.................................109
     Density e screen size...............................................................................................................109
     Immagini 9patch........................................................................................................................111
     Drawable complessi..................................................................................................................111
     Custom View per implementare un flat Button................................................................115
     Immagini Mipmap.....................................................................................................................117
     Vector Drawable........................................................................................................................117
     Organizzazione delle risorse..................................................................................................118
     Canvas, Paint e Shader.............................................................................................................121
     Color filter.................................................................................................................................. 126
     Utilizzo delle Custom View per migliorare le performance...........................................128
     Animazioni Android 2.x.......................................................................................................... 136
     Animazioni Android 3.0......................................................................................................... 138
     Animazioni Android 4.4.........................................................................................................143
     Animazioni Android 5.0.........................................................................................................144
     Gestione degli eventi touch...................................................................................................148
     Drag di una View con animazioni........................................................................................150

4.   SUPPORTO MULTIDEVICE di Fabio Collini................................................. 157
     Dimensioni degli schermi dei dispositivi Android........................................................... 157
     Gestione delle risorse al variare della dimensione dello schermo.............................. 159
     Gestione della orientation...................................................................................................... 162
     Gestione dei layout in base alla larghezza dello schermo............................................. 163
     Adattamento di un layout in base alle dimensioni.......................................................... 163
     Utilizzo dei Fragment...............................................................................................................164
     Gestione di una Activity multiFragment............................................................................ 167
     Gestione delle transaction..................................................................................................... 172
     Altri utilizzi dei Fragment....................................................................................................... 174
     Activity con singolo Fragment.............................................................................................. 174
     Custom View Vs Fragment.................................................................................................... 176

5.   BLUETOOTH di Stefano Sanna........................................................................ 179
     L’ultimo immortale................................................................................................................... 179
     Bluetooth Classic e Bluetooth Low Energy........................................................................180
     Panoramica del protocollo Bluetooth Classic................................................................... 182
     Panoramica del protocollo Bluetooth Low Energy...........................................................189
     Setup per sperimentazione.................................................................................................... 195
     Bluetooth Classic su Android...............................................................................................209
     Attivazione e visibilità.............................................................................................................210
     Discovery dei dispositivi ........................................................................................................ 212
     Pairing......................................................................................................................................... 216
     Discovery dei servizi................................................................................................................ 219
     Apertura diretta di connessioni RFCOMM....................................................................... 222
     Bluetooth Low Energy su Android....................................................................................... 223
     Bluetooth beacon.................................................................................................................... 230

 6
Sommario

     La tecnologia iBeacon............................................................................................................ 232
     Implementazione di un beacon........................................................................................... 235
     Scansione dei beacon in ambiente Android..................................................................... 238
     Beacon e geofencing............................................................................................................... 242
     Inversione di ruoli.................................................................................................................... 243
     Sicurezza e privacy................................................................................................................. 245

6.   ANDROID WEAR di Matteo Bonifazi............................................................ 249
     Android Wear idea..................................................................................................................250
     Android Wear design............................................................................................................. 252
     Notifiche tramite Android Wear......................................................................................... 255
     Android Wear App.................................................................................................................. 265
     Android Wear Watch face.................................................................................................... 287

7.   CHROMECAST E GOOGLE CAST di Alessandro Martellucci................... 305
     Che cos’è il Chromecast........................................................................................................ 305
     Installazione e configurazione.............................................................................................306
     Chromecast App..................................................................................................................... 307
     Google Cast............................................................................................................................... 313
     Applicazione Sender................................................................................................................314
     Il bottone di Cast...................................................................................................................... 318
     Il media router framework..................................................................................................... 319
     Il ruolo del Google Play Services.......................................................................................... 331
     La gestione del receiver da parte dell’applicazione client..............................................333
     La riproduzione del contenuto.............................................................................................340
     La comunicazione tra le applicazioni................................................................................. 345
     Il controllo del volume............................................................................................................ 350
     I sottotitoli.................................................................................................................................. 351
     Il logging.................................................................................................................................... 354
     Applicazione receiver............................................................................................................. 354
     Applicazione receiver: concetti avanzati........................................................................... 363
     Tipi e formati supportati........................................................................................................ 369
     Android TV............................................................................................................................... 370

8.   QUALITÀ DEL CODICE di Fabio Collini........................................................375
     Build dei progetti con Gradle.................................................................................................375
     Testing del codice.................................................................................................................... 378
     Tipologie di testing................................................................................................................. 379
     Unit test con JUnit................................................................................................................... 381
     Test di integrazione................................................................................................................. 387
     Robolectric................................................................................................................................ 387
     Testing end to end................................................................................................................... 389
     Acceptance test....................................................................................................................... 396
     Monkey testing........................................................................................................................ 397
     Copertura dei test................................................................................................................... 397

                                                                                                                                                    7
Android | Programmazione avanzata

      Analizzatori statici del codice.............................................................................................. 398
      Continuous Integration.......................................................................................................... 399
      Strategia di test di una applicazione Android..................................................................402
      Testing di codice legacy.........................................................................................................402
      Servizi web remoti.................................................................................................................. 404
      Dependency injection............................................................................................................405
      Dagger.........................................................................................................................................412
      Testing di codice dipendente dal tempo............................................................................ 425
      Testing su Java Virtual Machine di una applicazione Android....................................426
      Testing della UI con Espresso............................................................................................... 433
      Model View Presenter........................................................................................................... 435
      Task asincroni con Model View Presenter e RxJava.......................................................447
      Oggetti fake con Javassist.....................................................................................................450
      BDD e TDD con Espresso e Model View Presenter....................................................... 455

APPENDICE: SICUREZZA................................................................................... 457
      La sicurezza nell’azienda....................................................................................................... 457
      Utilizzo delle WebView.........................................................................................................463
      Android permission................................................................................................................468

INDICE ANALITICO............................................................................................. 475

 8
Prefazione

Quando gli autori di Android - Programmazione avanzata mi hanno chiesto di scrivere
la prefazione alla nuova edizione, il mio pensiero è andato immediatamente ai nu-
meri impressionanti che il sistema operativo di Google ha macinato in questi ultimi
anni, alla strada percorsa dal lancio del 2008 sul primo dispositivo targato HTC.
Senza voler entrare nel dettaglio dei singoli dati, basti pensare che, secondo le stime
di IDC, negli ultimi due anni circa 80 smartphone venduti su 100 sono stati equipag-
giati con il sistema operativo del robottino. Proiettato su scala globale, questo dato
significa un mercato potenziale di centinaia di milioni di persone.
Significa inoltre che, attorno al 2018, il fatturato delle app per Android supererà
quello generato dal principale concorrente, iOS di Apple. Non a caso, Flipboard ha
lanciato la propria versione per Android due anni dopo la versione per iOS, ma in
poco più di un anno la metà degli accessi arriva ormai da smartphone Android.
La motivazione per imparare a programmare applicativi per Android, però, non deve
limitarsi alla metrica numerica.
Perché leggere – e studiare – un volume dedicato a chi sviluppa in maniera avanzata
per Android? La risposta sta nell’impressionante successo e nelle previsioni di cre-
scita future, certo.
Un volume che tratta argomenti comuni per gli sviluppatori, con un approccio fuori
dal comune, e si spinge a trattare argomenti che i classici testi di programmazione
per Android spesso non considerano, non avrebbe un senso se non nella convinzione
che “Google stia per conquistare le nostre vite”, per riprendere le parole di Fastcode.
Provenendo dal mondo delle Telco, dove ho avuto la fortuna di lavorare al lancio
della prima rete UMTS al mondo, del primo cellulare con TV digitale mobile e del
primo Skypephone low cost, quando ancora gli smartphone non erano così diffusi, il
sistema operativo Android non è qualcosa di nuovo. Prima ancora, come giornalista
tecnologico, ho avuto l’opportunità di vivere le principali trasformazioni della telefo-
nia mobile, tra cui il declino dei sistemi operativi proprietari e l’esplosione delle app.

                                                                                       9
Android | Programmazione avanzata

Negli ultimi due anni sono successe, però, diverse cose che mi hanno fatto compren-
dere quanto pervasivo possa essere – parallelamente all’avanzata dell’Internet degli
oggetti – un sistema operativo così versatile e diffuso. Sono stato tra i pochi italiani
a poter ricevere i Google Glass durante il programma Explorer, e Android Auto è
qualcosa su cui ho lavorato negli ultimi 24 mesi per il debutto di Google nel mondo
dell’auto.
È da questo punto di vista, come osservatore privilegiato, che ho imparato ad ap-
prezzare Google come un risolutore di problemi in (quasi) ogni ambito della nostra
vita, una presenza amorfa che il Material Design – l’unificazione di tutti i prodotti
Google e app di terze parti sotto un unico cappello – rende concreta e possibile,
un sistema operativo che rompe le regole logiche e fisiche note fino a oggi per ri-
disegnare completamente il mondo che ci circonda. Un Google che da prodotto si
trasforma in presenza, con la giusta informazione sullo schermo giusto al momento
giusto. Cellulari, auto, console gaming, schermi del desktop, computer portatili, we-
arable e (forse) occhiali.
In un mondo così variegato, la completa padronanza del sistema operativo targato
Google è fondamentale per chi sviluppa applicativi complessi. Alessandro, Fabio,
Matteo e Stefano ci guidano, attraverso i capitoli di Android Programmazione Avan-
zata, nell’esplorazione di questo mondo affascinante e allo stesso tempo complesso.
Per chi condivide la visione sul futuro di Android (e Google), sviluppando applicativi
articolati, conoscerne gli anfratti più nascosti non può che rappresentare una tappa
fondamentale del proprio percorso professionale.

                                                               Massimo Cavazzini
                   Global Uconnect – Head of Marketing&User Experience EMEA region
                                                          Fiat Chrysler Automobiles

 10
Introduzione

Questo libro parla di una scommessa vinta. Android è il sistema operativo per dispo-
sitivi mobili più diffuso al mondo. In realtà, non solo dà vita a smartphone e tablet,
ma è presente in smartwatch, apparati televisivi, autovetture e sistemi embedded.
E non solo in prodotti commerciali, ma anche in progetti indipendenti, vista la sua
natura open source. L’ecosistema di Android si arricchisce costantemente di nuove
API, nuove librerie, nuovi strumenti di sviluppo, nuovo hardware compatibile, nuove
estensioni. Per la gioia degli sviluppatori e degli utenti. Sviluppatori motivati realiz-
zano prodotti che entusiasmano gli utenti, che a loro volta aumentano la domanda di
nuovi servizi e nuove applicazioni, che a sua volta alimenta la domanda di sviluppa-
tori sempre più specializzati. È inevitabile: laddove c’è una tecnologia così pervasiva
e ubiqua nella vita delle persone, in poco tempo si aprono spazi infiniti per nuove
idee, nuove possibilità.
L’obiettivo di questo libro è fornire agli sviluppatori che già conoscono le basi del-
la programmazione su Android le conoscenze per affrontare problematiche meno
comuni e trarre ispirazione dalle potenzialità più intriganti del sistema operativo.
Partendo dalla propria esperienza professionale consolidata, gli autori hanno sele-
zionato gli argomenti mirando alla crescita del lettore su due fronti: irrobustire la co-
noscenza dei temi “core”, al fine di migliorare la propria padronanza della piattafor-
ma (si vedano i temi sul supporto multidevice o la gestione dei task in background)
e stimolare nuove esplorazioni sui temi più attuali (wearable e interazione con ap-
parati televisivi).
Gli argomenti discussi nei vari capitoli comprendono riferimenti non solo alle li-
brerie standard di Android, ma anche ai molti progetti open source utilizzabili per
lo sviluppo di applicazioni per questo sistema operativo. Negli ultimi anni, infatti,
molte aziende (un tempo startup e adesso colossi spesso quotati in borsa) stanno
rilasciando librerie open source che semplificano varie fasi dello sviluppo. Square
è sicuramente una delle realtà più attive, ma anche Facebook, Yahoo!, Instagram

                                                                                     11
Android | Programmazione avanzata

e NetFlix annoverano vari progetti open source attraverso i quali stanno facendo
crescere varie community di sviluppatori. Un esempio molto significativo è quello
di RxJava (affrontato nel capitolo dedicato alla programmazione funzionale), una
libreria open source sviluppata da Netflix che sta rivoluzionando il modo di scrivere
il codice delle applicazioni Android.
In questo senso, pur se cristallizzato nelle sue pagine, questo libro è “vivo”, attualiz-
zato non solo nella mera versione delle API, ma anche negli obiettivi. È interessante,
infatti, notare come temi ritenuti avanzati nella prima edizione non lo siano più nella
seconda: è il caso delle notifiche push, ormai consolidate sia client-side sia server-
side, sulle quali è possibile trovare in rete numerosissimi esempi di codice e servi-
zi gratuiti che implementano le funzionalità di backend (per esempio, parse.com).
Altri, come NFC, hanno avuto poche evoluzioni (se non l’importante introduzione
della modalità HCE) e rispetto alle aspettative di tre anni fa sono rimasti argomenti
di nicchia.

A chi si rivolge questo libro
Questo libro è rivolto agli sviluppatori che hanno già una esperienza nello sviluppo di
applicazioni Android e che vogliono migliorare le proprie skill di programmazione su
questo sistema operativo mobile. Gli argomenti sono trattati partendo dal presuppo-
sto che il lettore abbia una conoscenza dei principali concetti dello sviluppo di una
applicazione Android.

Gli autori
Fabio Collini si occupa, all’interno dell’acceleratore di startup Nana Bianca di Firenze,
dello sviluppo di varie applicazioni disponibili nel Play Store. Dopo una esperienza su
piattaforma Java Enterprise, dal 2009 si occupa di progettazione e sviluppo di ap-
plicazioni Android. È attivo nella community sia come blogger (ha fondato e scrive
su cosenonjaviste.it) sia come speaker nelle principali conferenze a livello nazionale.
Come freelance, ha rilasciato due applicazioni che hanno ottenuto un buon numero di
download.
Matteo Bonifazi è Senior Android developer di Open Reply (Gruppo Reply) e Google
Developer Expert per la piattaforma Android. Ha partecipato alla realizzazione di im-
portanti progetti Android in campo nazionale e internazionale, riguardanti lo sviluppo
di applicazioni Android innovative e personalizzazioni del sistema operativo Android.
Collabora attivamente con il Google Developer Group di Roma, dove si occupa prin-
cipalmente di far conoscere alla comunità tutte le novità dell’ecosistema Android. È
speaker per le più importanti conferenze italiane e internazionali.

 12
Introduzione

Alessandro Martellucci è laureato in Informatica e da diversi anni segue il mercato
mobile, con particolare interesse per l’ecosistema Android. A oggi è Android deve-
loper presso OpenReply, società del gruppo Reply, e partecipa a progetti con diverse
peculiarità: dal video streaming all’installazione di Android su dispositivi con hardware
personalizzato. Nel 2014 ha partecipato al Droidcon UK con un seminario dedicato al
video streaming in Android, parlando del Chromecast e dell’Android TV.
Stefano Sanna è attualmente Manager presso Open Reply (Gruppo Reply), dove coor-
dina le attività di sviluppo di app native e ibride. Ha iniziato a sviluppare software per
dispositivi mobili nel 1999, su un Psion 5MX. Da allora ha lavorato su Java Micro Edi-
tion, Symbian, iOS e dal 2009 si occupa di Android per applicazioni commerciali. Ha
scritto due libri sullo sviluppo mobile e tenuto numerosi seminari su Java, Android e
Bluetooth in Italia e all’estero. Lasciati gli smartphone, ama giocare con i suoi bambini
a costruire robot e navi spaziali con i LEGO.

La struttura
Il libro è diviso in otto capitoli, ognuno dei quali contiene la trattazione di un argomen-
to specifico. In alcuni casi sono presenti riferimenti ad altri capitoli, per questo motivo
è consigliata la lettura nell’ordine in cui sono proposti.
Il Capitolo 1 descrive nel dettaglio il ciclo di vita delle Activity; pur essendo uno dei
primi argomenti affrontati quando ci si avvicina ad Android, non è sempre facile da di-
gerire. In questo capitolo sono affrontate le problematiche più comuni, prima fra tutte
la gestione dei task in background.
Il Capitolo 2 affronta la programmazione funzionale su Android: purtroppo ancora
non è possibile utilizzare Java 8 per lo sviluppo di applicazioni Android, anche se,
come mostrato in questo capitolo, Retrolambda è un’ottima alternativa. Gran parte
di questo capitolo è dedicata al framework RxJava, mostrando sia i concetti base sia
quelli più avanzati.
La grafica e la gestione dell’interfaccia utente sono l’argomento del Capitolo 3. Que-
sto capitolo contiene varie tecniche da utilizzare per sviluppare la parte di UI di una
applicazione. Fra gli argomenti trattati ci sono i Drawable, le animazioni, i Canvas e la
gestione degli eventi touch.
Gestire al meglio le risorse è fondamentale (ma non sempre facile) per creare layout
che si adattino ai vari dispositivi: il Capitolo 4 contiene un approfondimento su questo
tema, con particolare riferimento alla gestione del supporto multidevice e all’utilizzo
dei Fragment.
L’argomento presentato nel Capitolo 5 è Bluetooth, con una dettagliata trattazione di
Bluetooth Low Energy (BLE), la cui API ha fatto la sua comparsa su Android 4.3. BLE

                                                                                       13
Android | Programmazione avanzata

consente l’interfacciamento a dispositivi indossabili (tra cui le varie “band” per il fit-
ness) e, più in generale, è la tecnologia abilitante per la Internet Of Things.
Tra il 2015 e il 2016 si prevede che il numero dei televisori connessi alla rete sfiorerà
il miliardo di unità; Chromecast e Android TV (trattati nel Capitolo 6) rappresentano
solo l’inizio di questa nuova era tecnologica che colpirà le nostre vite. Il supporto da
parte di Mountain View, con il suo Google Cast, offre a tutti gli sviluppatori un mon-
do di possibilità ancora inesplorate: l’On Demand, il Gaming e l’Entertainment sono
solo alcuni tra gli argomenti più interessanti, sui quali tutti gli sviluppatori dovrebbero
scommettere.
Come cambia la user experience sui nostri polsi? Il Capitolo 7, dedicato ad Android
Wear, mostra nel dettaglio come sarà possibile estendere le proprie applicazioni su
tutti i nuovi smartwatch powered by Google.
Il testing su Android è il principale argomento del Capitolo 8: la prima parte contiene
una panoramica sui vari tool disponibili, da quelli per il testing fino a quelli per l’analisi
statica del codice e la continuous integration. Nella seconda parte sono analizzate al-
cune tecniche (come la dependency injection usando Dagger e il pattern Model View
Presenter) da utilizzare per scrivere codice testabile.
Completa il volume l’Appendice, dedicata alla sicurezza delle applicazioni Android;
questo tema viene affrontato mostrando alcune funzionalità messe a disposizione dal
sistema operativo utilizzabili per aumentare la sicurezza delle applicazioni Android.

Risorse
Sito web ufficiale del libro: http://www.androidavanzato.it
Repository codice: https://github.com/androidavanzato
E-mail per supporto e segnalazioni: androidavanzato@gmail.com
Twitter: @androidavanzato

Ringraziamenti
Gli autori ringraziano l’editore per la fiducia riposta, in particolare Marco Aleotti per il
suo supporto instancabile durante la scrittura e l’evoluzione dell’opera.
Fabio ringrazia Letizia per averlo sopportato nonostante, durante la scrittura del libro,
sia stato ancora più asociale del solito. Inoltre ringrazia Stefano per averlo coinvolto
in questo progetto, e Matteo e Alessandro per aver arricchito, con i loro importanti
contributi, gli argomenti trattati in questo libro.
Matteo dedica il suo lavoro alle persone che lo hanno aiutato in modo diretto e indiret-
to nella scrittura di questo libro. Push the limits!

 14
Introduzione

Alessandro ringrazia, in egual maniera, tutti coloro che lo hanno supportato e aiutato
durante la stesura del libro. È grazie a loro se il suo contributo è oggi migliore rispetto
a com’era all’inizio.
Stefano ringrazia in primis Fabio: senza la sua enorme tenacia e solidissima prepa-
razione questa seconda edizione non avrebbe conosciuto gli onori della stampa. Un
grazie sincero va ad Alessandro e Matteo, che hanno accolto con entusiasmo questo
progetto, contribuendo con temi freschi e appassionanti. Infine, dedica il risultato di
questo lavoro ai piccoli Riccardo e Alessandro, la cui intuizione, nel chiedere “Papà,
anche qui dentro c’è un piccolo computer?”, è misura della pervasività delle tecnologie
raccontate in questo libro.

                                                                                       15
1
Activity e task in background
                                                                               di Fabio Collini

Questo capitolo mostra nel dettaglio l’utilizzo delle Activity
all’interno di una applicazione, ponendo particolare attenzione
sull’esecuzione dei task in background. Sono analizzate le
varie soluzioni disponibili: sia quelle contenute nel framework
Android (come gli Async                   Task e gli Intent Service) sia
quelle utilizzabili attraverso librerie di terze parti.

Ciclo di vita di una Activity
Il concetto di Activity è uno dei più importanti nello sviluppo di una applicazione An-
droid ed è sicuramente il primo che ogni sviluppatore che si avvicina a questo siste-
ma operativo apprende. Nei primi esempi, a una Activity corrisponde una schermata
dell’applicazione; questa corrispondenza non è vera negli esempi più complessi, ma è
comunque un buon modo per familiarizzare con il concetto di Activity.
Scrivendo una applicazione Android che implementa il classico hello world, è necessa-
rio creare una classe che estende Activity e riscrivere un solo metodo: onCreate. Que-
sto metodo di callback viene invocato automaticamente in corrispondenza della cre-
azione dell’Activity, e di solito contiene il codice per inizializzare l’interfaccia grafica. Il
concetto di callback è ormai abbastanza comune a molti framework di sviluppo; in una
applicazione Android uno sviluppatore non deve scrivere una classe con un metodo
statico main invocato all’avvio. Un metodo main esiste, ma è nelle classi del framework
Android, in particolare nella classe ActivityThread. In pratica, non sono le classi scritte

                                                                                            17
Android | Programmazione avanzata

da uno sviluppatore che richiamano i metodi del framework; tali classi sono inserite
all’interno del framework e contengono dei metodi (chiamati, appunto, di callback)
richiamati in corrispondenza di alcuni eventi. Il principio che sta dietro questo modo di
organizzare le classi è chiamato anche principio Hollywood e può essere enunciato con
la frase don’t call me, I’ll call you.
Il ciclo di vita di una Activity non è banale da gestire; per questo motivo, il metodo on-
Create non è l’unica callback disponibile. Le callback principali sono sei; per analizzarle
meglio è possibile raggrupparle a coppie:
    • onCreate/onDestroy: richiamati, rispettivamente, dopo la creazione e prima che
        l’Activity sia distrutta. Il metodo onCreate contiene solitamente la creazione
        dell’interfaccia grafica; eventuali oggetti creati in questo metodo che necessi-
        tano di una chiusura esplicita (per esempio, le connessioni a database) sono
        gestiti nel metodo onDestroy;
    • onStart/onStop: richiamati prima che l’Activity diventi visibile e quando questa
        viene coperta da altre Activity. La callback onStart è il metodo giusto in cui scri-
        vere il popolamento dell’interfaccia grafica;
    • onResume/onPause: la differenza con le callback onStart/onStop è abbastanza
        sottile; sono richiamati sempre in sequenza tranne nel caso in cui l’Activity
        venga coperta da un’altra in modo parziale. In questo caso viene richiamato
        solo onPause e non onStop; quando l’Activity torna in primo piano viene richia-
        mato solo onResume. In pratica, dopo l’esecuzione di onStart e prima di onStop vi
        è la certezza che l’Activity sia visibile anche solo parzialmente; dopo onResume
        e prima di onPause l’Activity è visibile e in primo piano (per questo l’utente
        può anche interagire con le View contenute). Spesso la distinzione fra queste
        coppie di callback non è importante e, per questo motivo, non è necessario
        riscrivere tutti i metodi.

Un aspetto del ciclo di vita da tenere presente per non incorrere in errori consiste nel
fatto che i metodi onCreate e onDestroy sono invocati una sola volta su un oggetto; tutti
gli altri possono essere invocati più di una volta. È infatti abbastanza frequente il caso
in cui una Activity venga messa in background e ritorni successivamente in primo
piano (per esempio, dopo la pressione del tasto back).

Gestione dei metodi di callback comuni a più Activity
In alcuni casi può essere utile eseguire del codice in corrispondenza di una callback
per ogni Activity presente nell’applicazione; si pensi, per esempio, all’inizializzazione
di alcune librerie che permettono di tracciare l’utilizzo da parte degli utenti. Il modo

 18
Activity e task in background    Capitolo 1

più semplice è ovviamente quello di aggiungere l’invocazione di un metodo dentro
ogni callback; può essere utilizzato nel caso in cui il numero di Activity da gestire è
basso. Se l’applicazione contiene molte Activity, il copia incolla non è mai la soluzione
migliore e porta a codice difficilmente gestibile.

Classe base per il codice a comune
Una soluzione per evitare il copia incolla è quella che viene comunemente usata nello
sviluppo di codice object oriented: è possibile creare una classe base estesa da tutte le
Activity in cui fattorizzare il codice a comune. Anche questa soluzione ha comunque
delle controindicazioni dovute principalmente all’assenza dell’ereditarietà multipla in
Java. Una Activity può estendere una sola classe e quindi la gestione diventa proble-
matica nel caso in cui ci sia la necessità di estendere classi diverse (per esempio, Acti-
vity e ListActivity). In questi casi, avendo più classi da estendere, sarebbe comunque
necessario duplicare il codice a comune.

Utilizzo di ActivityLifecycleCallbacks
Con la release di Android 4.0 è stata aggiunta l’interfaccia ActivityLifecycleCallbacks
all’interno della classe Application. Per sfruttarla è necessario creare una classe che
estende Application e registrarla all’interno del manifest. All’interno della callback on-
Create della sottoclasse di Application è possibile registrare un oggetto che implemen-
ta ActivityLifecycleCallbacks; i metodi contenuti verranno invocati automaticamente
in corrispondenza delle callback di ogni Activity. Un esempio di utilizzo è il seguente:
@Override public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
        @Override public void onActivityCreated(
                Activity activity, Bundle savedInstanceState) {
            Log.d(TAG, "Activity created: " + activity.getClass().getSimpleName());
        }

        @Override public void onActivityStarted(Activity activity) {
            Log.d(TAG, "Activity started: " + activity.getClass().getSimpleName());
        }

        @Override public void onActivityResumed(Activity activity) {
            Log.d(TAG, "Activity resumed: " + activity.getClass().getSimpleName());
        }

        @Override public void onActivityPaused(Activity activity) {
            Log.d(TAG, "Activity paused: " + activity.getClass().getSimpleName());
        }

        @Override public void onActivityStopped(Activity activity) {

                                                                                         19
Android | Programmazione avanzata

                   Log.d(TAG, "Activity stopped: " + activity.getClass().getSimpleName());
               }

               @Override public void onActivitySaveInstanceState(
                       Activity activity, Bundle outState) {
                   Log.d(TAG, "State saved: " + activity.getClass().getSimpleName());
               }

               @Override public void onActivityDestroyed(Activity activity) {
                   Log.d(TAG, "Activity destroyed: " + activity.getClass().getSimpleName());
               }
         });
}

In questo modo la logica può essere scritta in un posto solo, potendo comunque ge-
stire comportamenti diversi in base all’Activity in oggetto sfruttando il parametro pas-
sato in ogni metodo.

Aspect Oriented Programming
L’aspect oriented è un paradigma di programmazione che può essere utilizzato per
risolvere problemi complicati sfruttando solo l’object oriented. La teoria che c’è dietro
l’aspect oriented è abbastanza complessa e i concetti che la compongono non sono
pochi. In questo paragrafo saranno illustrati solo quelli indispensabili per capire come
utilizzare l’aspect oriented. Il concetto principale è quello di aspect: rappresenta un
aspetto comune a più classi non necessariamente collegate fra loro da una gerarchia.
Sfruttando un aspect, è possibile modificare il comportamento delle classi sostituen-
do (in parte o completamente) alcune invocazioni di metodi presenti nel bytecode
delle classi. Gli esempi classici di aspect sono il logging e la gestione delle transazioni
su un database in una applicazione Java enterprise.
Un aspect può essere definito in modo concreto sfruttando altri due concetti:
   • pointcut: rappresentato solitamente da una stringa simile a una regular expres-
        sion, specifica quando un aspect deve essere applicato. È possibile agire su vari
        fattori per specificare quali metodi selezionare: oltre al nome del package, della
        classe o del metodo, è possibile selezionare anche tutte le sottoclassi di una
        certa classe o tutti i metodi con una specifica annotation;
   • advice: è il codice da eseguire ogni volta che viene eseguito un metodo compa-
        tibile con il pointcut corrispondente.

Un aspect può essere di tre tipi (è possibile scegliere quale usare in base alle esigenze):
  • before: l’advice viene eseguito prima del metodo originale;
  • after: l’advice viene eseguito dopo il metodo originale; è possibile scegliere se
      eseguirlo sempre oppure solo nel caso di terminazione corretta o con eccezioni;

    20
Activity e task in background     Capitolo 1

  •   around: l’advice viene eseguito al posto del metodo originale. All’interno
      dell’advice è possibile decidere in quali casi eseguire il metodo originale.

Per esempio, per loggare tutte le esecuzioni di uno o più metodi è possibile definire
un aspect di tipo before; per gestire le transazioni su un database è invece necessario
usare un aspect di tipo around. Un altro esempio facilmente implementabile usando
l’aspect oriented è la gestione di una cache delle chiamate a un metodo: usando un
aspect di tipo around, è possibile accedere ai parametri del metodo originale e al valo-
re di ritorno del metodo. Mantenendo in memoria una mappa che associa i parametri
al valore di ritorno, è possibile decidere se eseguire il metodo originale o ritornare un
valore precedentemente aggiunto nella mappa.
La cosa da sottolineare in questi casi è che l’advice è solitamente indipendente dal
metodo finale a cui è applicato; per esempio, nel caso di logging, è possibile usare un
solo advice per loggare tutti i metodi definiti dal pointcut. Questo è il motivo principale
per cui viene utilizzato: permette in modo semplice di scrivere codice a comune fra
classi non legate fra loro.
L’aspect oriented si basa su una modifica del codice per aggiungere la chiamata
all’advice; questa modifica può avvenire in tre momenti diversi:
    • build time: viene aggiunto uno step nel processo di build per modificare le
        classi compilate;
    • load time: le classi sono modificate nel momento in cui sono caricate in memo-
        ria dal class loader;
    • runtime: al posto delle classi originali sono utilizzati dei proxy che si occupano
        di gestire le chiamate agli advice.

Esistono varie librerie che permettono di usare l’aspect oriented in Java, ognuna delle
quali supporta una o più delle tre modalità appena viste. Per quanto riguarda lo svilup-
po su piattaforma Android, la libreria più usata è AspectJ, che funziona aggiungendo
uno step nel processo di build. Dopo che il compilatore Java ha creato i file .class, viene
lanciato il compilatore AspectJ che si occupa di modificare questi file. Utilizzando il
progetto gradle-android-aspectj-plugin (https://github.com/uPhyca/gradle-android-
aspectj-plugin), la configurazione del processo di build è banale, basta aggiungere al-
cune righe di configurazione nel file di build di Gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.+'
    }

                                                                                          21
Android | Programmazione avanzata

}
apply plugin: 'com.android.application'
apply plugin: 'android-aspectj'

A questo punto, per definire un aspect è possibile creare una nuova classe contenente
le annotation di AspectJ:
@Aspect
public class LogAspect {
    @Before("execution(* android.app.Activity+.*(..))")
    public void logMethod(JoinPoint joinPoint) {
        Log.d("callbacks", joinPoint.getSignature().getName());
    }
}

Per definire la classe come un aspect è stata utilizzata l’annotation Aspect, il pointcut è
definito utilizzando l’annotation Before. In queste poche righe di codice è stato definito
un blocco di codice (contenuto all’interno del metodo logMethod) che sarà richiamato
prima dell’esecuzione di un qualunque metodo di una sottoclasse di Activity (la regu-
lar expression passata all’annotation Before indica questo). Utilizzando il parametro
passato al metodo di tipo JoinPoint, è possibile accedere alle informazioni sul metodo
originale; da notare che il codice non dipende dalla signature del metodo originale. In
questo modo è possibile utilizzare lo stesso advice per gestire metodi di classi diverse
con signature differenti.
Per provare questa classe è necessario inserirla in un progetto Android opportuna-
mente configurato. Mettendo un breakpoint all’interno di un metodo di una Activity e
all’interno dell’advice, è possibile verificare che prima viene invocato l’advice e succes-
sivamente il metodo originale.
Per adesso l’aspect oriented non è molto diffuso all’interno della community di svilup-
patori Android; l’utilizzo probabilmente più famoso è all’interno della libreria di logging
hugo, sviluppata da Jake Wharton. In questa libreria sono sfruttati due pointcut per
identificare i metodi e i costruttori annotati con l’annotation DebugLog. L’advice è tipo
around, in quanto ha bisogno di eseguire una parte di codice prima del metodo origi-
nale per prendere il timestamp di inizio e dopo il metodo per calcolare la durata.

Flusso delle callback del ciclo di vita di una Actvity
Sono stati già analizzati i possibili metodi di callback relativi al ciclo di vita di una
Activity; in questo paragrafo saranno analizzate le sequenze più comuni in cui queste
callback possono essere invocate in base al comportamento dell’utente. Il caso più
comune (e anche il più semplice) è quello in cui una Activity viene creata per la prima
volta e visualizzata: sono richiamati, nell’ordine, i metodi onCreate, onStart e onResu-
me. A questo punto, l’Activity è visibile e l’utente può interagire con essa; le callback

 22
Activity e task in background     Capitolo 1

richiamate in seguito dipendono dall’interazione dell’utente e da altri eventi esterni
all’applicazione gestiti dal sistema operativo (per esempio, una chiamata in arrivo). In
particolare, possono esserci tre casi:
    1. l’utente preme il tasto back oppure l’Activity termina spontaneamente richia-
       mando il metodo finish: sono invocati nell’ordine i metodi onPause, onStop e onDe-
       stroy. A questo punto, l’Activity viene distrutta e il garbage collector di Java può
       liberare la memoria distruggendo l’oggetto corrispondente;
    2. l’Activity viene messa in background in quanto un’altra Activity viene eseguita:
       questo accade spesso e può verificarsi in diversi casi, per esempio quando l’u-
       tente preme il tasto Home (anche la home di Android è una Activity), quando
       viene aperta un’altra Activity della stessa applicazione, oppure quando eventi
       esterni (come una chiamata in arrivo) causano l’apertura di una nuova Activity.
       In questi casi viene richiamato il metodo onPause e, solo se l’Activity è coperta
       totalmente dalla nuova Activity, il metodo onStop;
    3. cambio di configurazione del dispositivo: avviene quando c’è un cambio di
       orientation (portrait o landscape), ma anche in casi meno frequenti, per esem-
       pio quando viene aperta la tastiera fisica di un dispositivo. In questo caso l’Ac-
       tivity viene distrutta e viene creata una nuova istanza della stessa Activity. Le
       callback richiamate sono quelle già viste: onPause, onStop e onDestroy sulla vec-
       chia Activity e onCreate, onStart e onResume sulla nuova Activity.

Gestire i vari casi può non essere semplice; particolare attenzione va posta nel testare
il cambio di configurazione, in quanto può avvenire in qualunque momento. In questi
casi l’utente si aspetta di ritrovare l’Activity nello stesso stato in cui era in precedenza;
il prossimo paragrafo analizzerà questo aspetto.

Salvataggio dello stato di una Activity
In ogni momento su un dispositivo Android sono in esecuzione più applicazioni, ognu-
na delle quali può avere nel proprio stack più Activity aperte. Ogni volta, infatti, che
viene aperta una Activity, quella di partenza rimane nello stack in modo da poter es-
sere riportata in primo piano nel caso di pressione del tasto back. In caso di necessità
di memoria, alcune applicazioni (o alcune Activity di una o più applicazioni) possono
essere terminate in automatico dal sistema operativo.
Per poter salvare il proprio stato interno è necessario sovrascrivere il metodo onSaveIn-
stanceState della classe Activity. Questo metodo ha un parametro di tipo Bundle in cui
è possibile salvare tutti gli oggetti da ripristinare in seguito. Il restore dei parametri può
avvenire in due metodi che possono essere riscritti in una Activity:

                                                                                            23
Android | Programmazione avanzata

  •     onCreate: il parametro passato a questa callback è un Bundle in cui sono presenti
        gli oggetti precedentemente salvati. Nel caso si tratti della prima esecuzione,
        questo parametro ha valore null;
  •     onRestoreInstanceState: callback da riscrivere per eseguire il restore, viene in-
        vocata in automatico dopo la callback onStart nel caso in cui ci sia uno stato
        salvato in precedenza.

I Bundle sono molto utilizzati nelle classi del framework di Android, per esempio anche
il passaggio di parametri a una Activity avviene usando un Intent che internamen-
te utilizza un Bundle. Un Bundle può essere visto come una mappa di coppie nome-
valore; il nome è sempre una stringa, mentre il valore è un tipo primitivo Java o un
oggetto serializzabile. Il concetto di oggetto serializzabile nello sviluppo Android è un
po’ diverso da quello standard dello sviluppo Java, infatti comprende anche gli oggetti
che implementano l’interfaccia Parcelable oltre a quelli che implementano l’interfaccia
Java standard Serializable.
L’interfaccia Parcelable è stata introdotta nel framework Android per questioni di per-
formance; infatti non fa uso di reflection per leggere e scrivere i valori dei campi di un
oggetto, ma delega il tutto a una implementazione che deve essere scritta dallo svilup-
patore. La scrittura dei campi avviene nel metodo writeToParcel, mentre la creazione
di un oggetto, leggendo i dati salvati in precedenza, avviene nei metodi di un campo
statico della classe di tipo Parcelable.Creator. Un esempio di implementazione di una
classe con due campi è il seguente:
public class Person implements Parcelable {
    private String name;
    private String surname;

      @Override public int describeContents() {
          return 0;
      }

      @Override public void writeToParcel(Parcel dest, int flags) {
          dest.writeString(name);
          dest.writeString(surname);
      }

      protected void readFromParcel(Parcel in) {
          name = in.readString();
          surname = in.readString();
      }

      public static final Parcelable.Creator CREATOR =
              new Parcelable.Creator() {
          public Person createFromParcel(Parcel in) {
              Person person = new Person();

 24
Puoi anche leggere