Android è il nome che Google e la Open Handset Alliance hanno dato a una piattaforma, basata sul sistema operativo Linux, per l‘esecuzione di applicazioni mobili. Non si tratta di un microbrowser o di una singola applicazione ma di un intero stack che parte dal sistema operativo Linux fino all‘utilizzo di una Virtual Machine specifica di cui esamineremo le caratteristiche principali.
Come sappiamo Google non è solo il nome che si associa al celeberrimo motore di ricerca, ma è una fonte inesauribile di idee specialmente in ambito Web2.0. È sufficiente andare all’indirizzo labs.google.com [1] per accorgersi di tutti gli strumenti che questa azienda mette a disposizione quali API per la realizzazione di applicazioni basate, ad esempio, sull’utilizzo delle Google Map o sugli stessi strumenti di ricerca del famoso motore. Nonostante la grande crisi economica mondiale che ha suggerito al gigante della rete di accantonare alcuni progetti meno “essenziali”, in questi ultimi mesi Google ha comunque continuato a sviluppare le sue idee per quel mercato difficilissimo rappresentato dai dispositivi mobili, in cui concorrenti come Sony Ericcson, Nokia, Microsoft e molti altri la fanno da padrone.
Sta quindi sempre più maturando Android che, come vedremo meglio nel presente articolo, non è un microbrowser, e nemmeno una applicazione installabile sul proprio telefono Symbian, Windows CE o sul novello iPhone. Si tratta di un intero stack che parte dal sistema operativo fino ad una Virtual Machine per l’esecuzione delle applicazioni mobili.
Caratteristica fondamentale di tutto ciò è l’utilizzo di tecnologie Open Source a partire dal sistema operativo che è Linux con il Kernel 2.6, fino alla specifica virtual machine per l’esecuzione di applicazioni che si chiama Dalvik. Il tutto è guidato dalla Open Handset Alliance (OHA) [2] ossia da un gruppo di 47 aziende (numero in continua crescita), il cui compito è quello di studiare un ambiente evoluto per la realizzazione di applicazioni mobili. Ma perchè si è deciso di realizzare l’intero stack? Quello che già esisteva (Symbian, J2ME, Windows CE, iPhone) non andava bene? In questo articolo vedremo di dare una risposta a queste domande elencando le caratteristiche principali, di interesse per noi sviluppatori, di questo nuovo ambiente che descriverò in modo approfondito nel libro che sarà pubblicato in PDF nei prossimi mesi qui su MokaByte e che sarà utilizzato nei corsi che andrò a tenere dal mese di febbraio (http://www.massimocarli.it/site/index.php?option=com_content&task=view&id=540&Itemid=43).
L’architettura di Android: Java dov’è?
Quando si introduce Android si utilizza sempre una famosa immagine che ne descrive l’architettura (Figura 1). In questo articolo non ci dilungheremo nella spiegazione di ciascuno dei componenti, ma utilizzeremo l’immagine per inquadrare quello che è l’elemento forse più importante per noi sviluppatori ossia la Dalvik VM. Notiamo come essa faccia parte dell’ambiente di runtime e sia costruita sui servizi offerti dal kernel e dalle diverse librerie native. Notiamo inoltre come l’altro elemento importante del runtime sia costituito dalle core libraries.
Figura 1 – L’architettura di Android
Ciò che l’architettura non mette in evidenza è il ruolo di Java in tutto questo. In una architettura Android non esiste alcuna virtual machine Java e non viene eseguito alcun bytecode Java. Il fatto che Android non fosse una specializzazione della piattaforma Java ME l’avevamo capito nell’introduzione per cui perchè parliamo di Java? Semplicemente perchè per sviluppare applicazioni per Android si utilizza Java. Ma se si utilizza Java perchè non si è utilizzata la Java ME? Beh, la piattaforma Java ME purtroppo non ha avuto lo stesso successo delle sorelle Java Standard Edition e Java Enterprise Edition in quanto non ha mantenuto la promessa del “Write Once, Run Everywhere”. I dispositivi mobili in grado di eseguire delle MIDlet sono moltissimi e molto diversi tra di loro. Realizzare delle applicazioni che funzionano bene e sfruttano a dovere le caratteristiche di ciascun dispositivo si è rivelata cosa impossibile. Un dispositivo può promettere di eseguire applicazioni MIDP 2.0 allo stesso modo di un altro ma può avere dimensioni, risoluzione, modalità di input diverse. Alcuni hanno il bluetooth altri no, alcuni hanno la fotocamera e altri no. Per questo motivo si è portati a realizzare applicazioni specifiche per classi di dispositivi come possono essere quelli raggruppati sotto il nome di “classe 60” di Symbian.
Un altro aspetto molto importante di Java ME è il suo legame con la piattaforma padre Java SE di cui è un sottoinsieme. Attraverso la classificazione in Configuration e Profile si è infatti deciso di eliminare dalla versione Java SE tutte quelle istruzioni ed API non in grado di poter essere eseguire in un dispositivo con risorse limitate in termini di CPU e memoria. La Java ME non è quindi stata pensata appositamente come piattaforma mobile ma come “l’insieme delle API che funzionano anche in dispositivi mobili”. La OHA e Google hanno quindi deciso che la cosa migliore per la realizzazione di una piattaforma mobile fosse quella di creare subito qualcosa di ottimizzato e specifico senza ricadere nel reinvent the wheel per i componenti principali.
OK, fin qui abbiamo capito che la Java ME non c’è ma allora Java cosa c’entra? Un obiettivo non secondario della nuova piattaforma è quello di rendere relativamente semplice la realizzazione di applicazioni che alla fine sono quelle che ne determinano il successo. Le possibilità erano quelle di creare un nuovo linguaggio oppure di utilizzarne uno esistente ereditando una community di sviluppatori e soprattutto un insieme maturo di strumenti di sviluppo. La scelta è caduta su Java non solo per questi motivi ma anche per la possibilità di avere a disposizione un bytecode di specifiche conosciute (e, per i maligni, pure libero da qualunque royalty per la certificazione TCK) e quindi modificabile e ottimizzabile a piacere.
Nel testo approfondiremo maggiormente le caratteristiche della Dalvik VM [3], per il momento diciamo semplicemente che si tratta di una Virtual Machine progettata e realizzata da Dan Borstein e che ha come principale caratteristica quella di essere register based diversamente dalla KVM che è invece stack based. Senza dilungarsi in dettagli [4] diciamo che un utilizzo intelligente dei registri di sistema permette una maggiore ottimizzazione della memoria in dispositivi con bassa capacità. Si tratta inoltre di una VM ottimizzata per l’esecuzione contemporanea di più istanze sfruttando la gestione di processi, memoria e thread del sistema operativo sottostante. Ovviamente la Dalvik VM non esegue bytecode Java ma un qualcosa che si può ottenere da esso e che prende il nome di Dalvik bytecode. Ecco svelato l’arcano. Le applicazioni per Android si sviluppano in Java sfruttando i tool di sviluppo classici come Eclipse o NetBeans per poi trasformare il bytecode Java in Dalvik bytecode. Ecco che su un dispositivo Android non girerà alcun bytecode Java ma un bytecode le cui specifiche sono descritte dal formato DEX (Dalvik EEecutable). Ecco che le core libraries e tutte le API che avremo a disposizione nella realizzazione delle applicazioni per Android saranno classi Java.
I componenti principali di Android
La caratteristica della DVM di poter eseguire diverse istanze contemporanee in modo ottimizzato non è da sottovalutare. Questo perchè Android associa a ciascuna applicazione, distribuita all’interno di un file apk, un singolo task a cui viene data la responsabilità di gestire più activity ossia quelli che sono i componenti più importanti di una qualunque applicazione per questo sistema. Possiamo quindi dire che gli elementi fondamentali di Android, dal punto di vista dello sviluppatore, sono i seguenti:
- Activity
- Intent e IntentFilter
- Broadcast Intent Receiver
- Service
- Content Provider
Activity
Potremmo definire una Activity come una schermata di una applicazione di Android ossia un qualcosa che visualizza delle informazioni o permette l’inserimento di dati da parte dell’utente attraverso la renderizzazione di quelle che chiameremo View. Una applicazione sarà per lo più costituita da più Activity ciascuna delle quali verrà eseguita da un proprio processo all’interno di uno o più task. Il compito degli sviluppatori sarà quindi quello di creazione delle diverse Activity attraverso la descrizione delle View e la descrizione delle modalità con cui le stesse si passano le informazioni. Di fondamentale importanza è la gestione del ciclo di vita delle attività attraverso opportuni metodi di callback. Si tratta di un aspetto importante di Android a seguito della politica di gestione dei processi delegata per lo più al sistema che, in base alla necessità, può decidere di “killarne” uno o più. In quel caso si dovranno adottare i giusti accorgimenti per non incorrere in perdita di informazioni. Da notare come attraverso il plugin fornito da Google sia possibile definire le View in modo dichiarativo attraverso alcuni file XML di configurazione.
Intent e IntentFilter
Come abbiamo accennato l’architettura di Android è ottimizzata in modo da permettere uno sfruttamento migliore delle risorse disponibili. Per raggiungere questo scopo si è pensato di “riciclare” quelle attività che svolgono operazioni comuni a più applicazioni. Per fare un esempio consideriamo la semplice selezione di un contatto dalla rubrica. Il fatto che ciascuna applicazione possa gestire il modo con cui una azione avviene ha il vantaggio di permettere una maggiore customizzazione delle applicazione ma ha il grosso svantaggio di fornire diverse modalità, spesso pure simili tra di loro, per eseguire una stessa operazione. Un utente che utilizza un dispositivo si aspetta di eseguire la stessa operazione sempre nelle stesso modo in modo indipendente dall’applicazione. Ecco che si è deciso di adottare il meccanismo degli Intent che potremmo tradurre in “intenzioni”. Attraverso un Intent, una applicazione può dichiarare la volontà di eseguire una particolare azione senza pensare a come questa verrà effettivamente eseguita. Nell’esempio precedente il corrispondente Intent potrebbe essere quella che dice “devo scegliere un contatto dalla rubrica”. A questo punto serve un meccanismo che permetta di associare tale Intent ad una Activity per la sua esecuzione. Ciascuna Activity può dichiarare l’insieme degli Intent che la stessa è in grado di esaudire attraverso quelli che si chiamano IntentFilter. Se una Activity ha tra i propri IntentFilter quello relativo alla scelta di un contatto dalla rubrica, quando tale Intent viene richiesto essa verrà visualizzata per permettere all’utente di eseguire l’operazione voluta. Tale attività sarà la stessa per ogni applicazione senza la necessità di definirne una propria. Questo utilizzo degli Intent riguarda la comunicazione tra più Activity.
Broadcast Intent Receiver
È possibile comunque utilizzare lo stesso meccanismo con eventi che non provengono direttamente da una applicazione come ad esempio la ricezione di una telefonata, di un SMS o il segnale di batteria scarica. Questi eventi vengono gestiti attraverso i Broadcast IntentReceiver che è possibile configurare attraverso l’ormai stranoto meccanismo dei listener.
Service
In precedenza abbiamo associato le Activity a delle schermate. Nel caso in cui si rendessero necessarie delle funzionalità long running (di esecuzione prolungata) non direttamente legate ad aspetti visuali si rende necessaria la creazione di uno o più Service. Parliamo quindi di processi con la responsabilità di riprodurre file multimediali, leggere o scrivere informazioni attraverso la rete o attraverso le informazioni dell’eventuale GPS integrato.
Content Provider
Dall’immagine dell’architettura notiamo come Android metta a disposizione un SQLite [5] per la gestione della persistenza di informazioni comunque limitate a ciascuna singola applicazione. Se si intende mettere a disposizione un insieme di dati per più applicazioni, che ricordiamo sono in esecuzione in processi diversi, è di fondamentale importanza il concetto di Content Provider. Esso rappresenta una interfaccia comune con cui wrappare una serie di sorgenti dati come quelle rappresentate da DB SQLite come accennato sopra, ma anche l’accesso a dati di tipo diverso come quelli GPS provenienti da una antenna o la classica rubrica.
Quelli descritti sono quindi gli elementi alla base di ciascuna applicazione per android che quindi è necessario saper padroneggiare per un utilizzo ottimizzato di tutte le risorse disponibili.
Le caratteristiche di Android
Dopo aver descritto i componenti principali dell’architettura di Android vediamo di descrivere quegli aspetti che lo rendono diverso dalle tecnologie o architetture alternative e che possiamo riassumere di seguito.
Definizione dichiarativa della UI
Attraverso l’utilizzo di opportuni documenti XML, facilmente gestibili con il plugin messo a disposizione da Google, è possibile creare in maniera dichiarativa l’interfaccia grafica delle applicazioni (Figura 2). Lo stesso plugin permette di avere, in ogni momento, una preview del risultato dell’interfaccia realizzata.
Figura 2 – Definizione dichiarativa della UI
Ciascuna applicazione può essere consumer e provider di informazioni
Utilizzando il meccanismo degli Intent e dei Content Provider è possibile fare in modo che le diverse applicazioni collaborino tra di loro per la gestione dei contenuti secondo il paradigma Web 2.0. Si tratta quindi di un vero e proprio ambiente all’interno del quale più applicazioni possono convivere con un utilizzo ragionato delle risorse. A tale proposito possiamo pensare ad Android come una vera e propria piattaforma che mette a disposizione una serie di strumenti che è possibile utilizzare in modo relativamente semplice all’interno delle nostre applicazioni. Pensiamo quindi alla possibilità di accedere ai servizi di Google Map per la realizzazione di applicazioni location based, o alla semplicità con cui è possibile interagire con i servizi di telefonia o di gestione degli sms o con lo stesso browser integrato. Lo sviluppatore si concentrerà su quelli che sono i servizi di business senza preoccuparsi della realizzazione di strumenti a supporto che potremo comunque realizzare avendo a disposizione un intero stack.
Il codice sorgente è Open Source
Android non solo utilizza tecnologie open source ma il suo stesso codice è ora disponibile [6] sotto la licenza Apache 2.0.
È basata sulle API della Java SE ma non esegue bytecode Java
Per quello che riguarda le API Java disponibili queste sono relative alla piattaforma Java SE (e non a quella Java ME) con un numero di sviluppatori sicuramente superiore che quindi può iniziare a sviluppare applicazioni Android con una curva di apprendimento molto breve. Notiamo come l’analogia con la Java SE sia stata fatta a livello di API e non di implementazione. L’applicazione in esecuzione sul dispositivo Android viene eseguita all’interno di una VM che è strettamente legata alle risorse del sistema operativo Linux. Questo significa che l’applicazione pseudo-Java è praticamente nativa rispetto al dispositivo con notevoli vantaggi dal punto di vista delle prestazioni. In un dispositivo Android non viene eseguito bytecode Java e non esiste alcuna VM Java.
Sono tutte caratteristiche che fanno di Android una piattaforma di grande interesse che impararemo a padroneggiare per la realizzazione di applicazioni molto interessanti.
Le applicazioni di Android
Come detto il successo di una piattaforma come Android verrà deciso dalle applicazioni disponibili. A tale proposito la politica di Google è molto chiara e prevede la possibilità di utilizzo di un ambiente di sviluppo e di un emulatore per il test delle applicazioni. Da pochi giorni è poi nato Android Market [7] dove chiunque, dopo una spesa di 25$, può vendere (o regalare) le proprie applicazioni. Una politica quindi per certi versi opposta a quella dell’iPhone dove per sviluppare le applicazioni è necessario non solo registrarsi alla corrispondente comunità di sviluppatori ma utilizzare anche strumenti e canali ben definiti. Non ci resta quindi che dare sfogo alla mostra fantasia e realizzare non solo i classici giochi ma soprattutto applicazioni che sfruttano le potenzialità delle mappe di Google e la possibilità di interagire con le funzionalità del telefono. Pensiamo non solo alla possibilità di cercare i ristoranti o altri punti di interesse vicini alla nostra attuale posizione ma anche di determinare il tragitto per arrivarvi o iniziare una chiamata per la prenotazione. Sebbene non si tratti certo di una applicazione originale, con Android la novità consiste nella semplicità con cui la stessa può essere realizzata e nel fatto che essa potrà veramente essere fruita da tutti i dispositivi abilitati, che cominceranno presto a essere disponibili prodotti da varie aziende.
Conclusioni
In questo breve articolo abbiamo descritto solo alcune delle principali caratteristiche di Android che, con il lancio dei primi Google Phone, si vorrà affermare come piattaforma per la realizzazione di applicazioni mobili di sicuro successo. Molto dipenderà non solo da Google o dalla OHA, ma anche dalle scelte che i grandi colossi dell’hardware telefonico come Nokia prenderanno nei prossimi mesi. Se, come pare, saranno presto disponibili vari modelli di “telefoni” perfettamente compatibili con la piattaforma Android, potremmo assistere all’affermarsi di una tecnologia estremamente promettente.
Riferimenti
[1] Google Labs
[2] Open Handset Alliance
http://www.openhandsetalliance.com/
[3] Dalvik Virtual Machine
[4] Virtual Machine Showdown: Stack versus Registers
http://www.sagecertification.org/events/vee05/full_papers/p153-yunhe.pdf
[5] SQLite
[6] Codice sorgente Android con licenza Apache 2.0
http://www.apache.org/licenses/
[7] Android Market
http://www.android.com/market/