venerdì 18 febbraio 2011

Android, il processo di sviluppo

Grazie all'uso di opportuni plugin il processo di sviluppo per applicazioni Android può essere seguito all'interno dell'IDE stesso. Sono disponibili plugin sia per Eclipse che per NetBeans, due dei più famosi ambienti di sviluppo per applicazioni Java. Esistono almeno due buoni motivi per conoscere e saper avviare il processo di sviluppo di un'applicazione Android anche senza l'uso dei suddetti plugin. Il primo è che, come dicevo poco fa, il plugin per sviluppare le applicazioni Android è disponibile solo per Eclipse e NetBeans. Pertanto, se il vostro IDE preferito non è fra questi non vi resta che utilizzare i tool messi a disposizione dal SDK (Service development kit) per Android. Il secondo motivo, invece, è strettamente didattico. Per imparare i meccanismi nascosti proprio dai plugin consiglio, almeno una volta, lo sviluppo di un'applicazione Android (anche semplice) attraverso i tool del SDK. Ecco cosa offre il il SDK di Android:
  • Android: comando per creare e aggiornare progetti e/o generare AVD (Android virtual device), i dispositivi Android virtuali usati dall'emulatore;
  • Android emulator: permette di emulare un terminale Android, consentendo l'installazione delle applicazioni sviluppate;
  • Android debug bridge: favorisce l'interazione con il dispositivo emulato o collegato;
Il SDK di Android va poi completato con altri tool esterni, occorrono infatti altre applicazioni: Ant, per compilare il progetto (in un unico file apk); Keytool (opzionale), per generare una chiave utile a segnare l'applicazione scritta; Jarsigner (opzionale), per usare la chiave generata sull'applicazione. Vi occorre ovviamente una versione di JDK (Java development kit) e un editor di testi.
La creazione di un nuovo progetto avviene con il comando android che, se non è seguito da alcuna opzione, avvia anche la schermata principale del tool attraverso cui possiamo gestire (graficamente) gli aggiornamenti delle piattaforme di sviluppo, i terminali virtuali e avviare l'emulatore.
Per creare un nuovo progetto va passato al comando android l'opzione create project, seguita dagli argomenti che caratterizzeranno il nuovo progetto, questa la sintassi: android create project --target target_id --name project_name --path path_of_project --activity name_of_activity --package name_of_package, dove:
  • --target indica la piattaforma da usare per lo sviluppo dell'applicazione. La lista delle piattaforme disponibili sul proprio computer può essere ottenuta con il comando android list targets;
  • --name specifica il nome del progetto;
  • --path indica la directory da usare per il progetto (se non esiste verrà creata nella directory di lavoro);
  • --activity specifica il nome dell'attività eseguita all'avvio dell'applicazione. Questo argomento permette di generare la classe Java che descrive l'attività;
  • --package indica il nome per il package del progetto;
Ad esempio, il comando android create project --target 1 --name FirstApp --path /home/user/FirstApp --activity FirstAppActivity --package android.firstapp crea la cartella /home/user/FirstApp con all'interno la struttura utile allo sviluppo dell'applicazione. Queste le cartelle e i file generati:
  • AndroidManifest.xml: il manifesto dell'applicazione;
  • build.xml: il file xml utile alla compilazione con ant;
  • default.properties: file con le proprietà di default per la compilazione (non modificatelo);
  • build.properties: file usato per sovrascrivere le proprietà da usare in fase di compilazione;
  • local.properties: file con le proprietà locali per ant, quelle aggiunte da noi;
  • src/ raccoglie la struttura, secondo le disposizioni dettate dal package di appartenenza, che ospita il codice sorgente dell'applicazione;
  • bin/ raccoglie il prodotto della compilazione, il file apk (da usare per installare l'applicazione), il file dex (l'applicazione compilata per l'esecuzione sulla DVM) e le classi compilati (all'interno di altre cartelle);
  • gen/ raccoglie i file generati automaticamente da ant, è qui che si trova la famosa classe R.java (che associa le risorse agli id, per referenziarli all'interno del codice);
  • libs/ raccoglie le librerie esterne usate dall'applicazione (se presenti);
  • res/ raccoglie le risorse utilizzate nell'applicazione;
  • tests/ raccoglie una copia della struttura fin qui vista, utile per svolgere test (opzionale);
Con il comando android possiamo inoltre aggiornare un vecchio progetto attraverso l'opzione update project e i parametri --name project_name --target id --path path_to_your_project, dove:
  • --name è il nuovo nome del progetto (parametro opzionale se non vogliamo modificare il nome);
  • --target specifica un nuovo target per l'applicazione;
  • --path indica il path del progetto da aggiornare (parametro indispensabile);
Ad esempio, il comando android update project --path /home/user/FirstApp --name FirstAppV2 modifica il nome dell'applicazione creata prima (eseguite una copia della vecchia applicazione quando ne modificate il target o il nome, per una nuova versione). La compilazione avviene eseguendo il comando ant nella cartella di progetto. L'installazione sul terminale, invece, avviene attraverso il comando adb install FirstAppV2.apk (eseguito all'interno della cartella di progetto).
Per rimuovere l'applicazione sul dispositivo virtuale, infine, abbiamo due possibilità. La prima, ovviamente, è attraverso l'interfaccia grafica del dispositivo emulato. Troviamo un elenco delle applicazioni installate nella scheda "Scaricate" oppure "In esecuzione" della voce "Gestisci applicazioni" del menu "Impostazioni, Applicazioni". Selezionando un'applicazione dall'elenco possiamo decidere se terminarla (task manager di Android) o disinstallarla. La seconda possibilità prevede invece l'uso del terminale, con il comando adb shell (che trovate nella cartella plattform-tools/) accediamo al terminale del dispositivo. Per cancellare l'applicazione è sufficiente digitare il comando rm /data/app/nome_applicazione. Per cercare il nome dell'applicazione e ottenere un elenco completo delle applicazioni esterne installate vi coniglio di provare con il comando ls /data/app/.
Attenzione, se non avete aggiunto una nuova variabile di ambiente al vostro sistema operativo (un nuovo path in cui il terminale deve cercare i comandi), i comandi saranno eseguibili solo se la directory di lavoro coincide con la directory che ospita i comandi (anteponendo agli stessi il path per la ricerca locale ./).

giovedì 17 febbraio 2011

Android, introduzione alle applicazioni

Le applicazioni per Android sono scritte in Java. Tuttavia, il bytecode generato dalla compilazione viene ottimizzato dal tool di sviluppo e l'applicazione viene eseguita sul dispositivo all'interno di una Dalvik Virtual Machine (DVM), una macchina virtuale molto più leggera della classica Java Virtual Machine (JVM). La DVM è infatti ottimizzata per l'esecuzione su dispositivi mobili, richiede poca memoria e permette pertanto l'istanza di più DVM sullo stesso dispositivo!
La distribuzione delle applicazioni avviene attraverso file apk (Android package), una variante del file JAR (gli archivi Java). All'interno di un file apk (che possiamo aprire con un gestore di archivi compressi, vi invito a farlo) troviamo le directory e i file destinati alle risorse (cartella res/ e file resources.arsc) e quella per le informazioni (cartella META-INF/), oltre ai file che descrivono al sistema operativo l'applicazione (AndroidManifest.xml, il manifesto dell'applicazione) e l'applicazione stessa (impacchettata in unico file, classes.dex).
Non va mai dimenticata una cosa: il kernel Linux è alla base di Android! Ogni applicazione viene eseguita all'interno di un processo Linux che dispone della propria virtual machine sicché il codice in esecuzione risulta isolato dal codice delle altre applicazioni. Questo conferisce al sistema operativo e alle applicazione un certo grado di stabilità. Esistono, ovviamente, delle tecniche per la comunicazione fra processi.
Le prestazioni delle applicazioni all'interno del sistema operativo derivano da un'attenta scomposizione dei componenti e delle risorse che la descrivono. La loro esecuzione può inoltre avvenire da più punti di accesso al codice del programma, questo permette al sistema operativo di eseguire all'occorrenza un preciso pezzo di codice piuttosto che l'intera applicazione! Tale necessità è ad esempio utile ad un'applicazione per invocare le funzionalità già sviluppate in un'altra applicazione. Per comprendere la suddetta modularità e per sfruttarla all'interno delle proprie applicazioni è necessario studiare e programmare pochi componenti (non necessariamente tutti, dipende dalla complessità dell'applicazione). Segue una loro breve descrizione:
  • Attività (Activity): rappresenta la schermata che consente all'utente l'interazione con l'applicazione, raccogliendo gli elementi che compongono l'interfaccia grafica e disponendoli secondo un opportuno layout. Ogni attività, implementata come sotto classe della classe Activity (del package android.app.Activity), è indipendente da un'altra. Solitamente un'attività svolge una precisa azione per l'applicazione, essa può essere orientata all'input dei dati, alla presentazione dell'output oppure a entrambe. Tutto dipende da come viene progettata dal programmatore. Nonostante l'indipendenza detta prima, le attività possono in ogni caso cooperare fra di loro per l'implementazione di una delle due fasi dette prima. In tal caso ci sarà un'attività principale che, dopo l'input o l'elaborazione dei dati, chiederà al sistema operativo il passaggio a una seconda attività, passando a quest'ultima le opportune informazioni. Il contenuto visivo dei componenti viene offerto da oggetti della classe View (del package android.view.View). Un'attività, quindi, contiene oggetti della classe View (bottoni, aree di testo, etichette, etc...);
  • Servizi (Services): lo svolgimento in background di una determinata funzione viene garantito da un preciso servizio, anche quando l'utente sta eseguendo altre operazioni sul dispositivo. Poiché un servizio non dispone di un'interfaccia grafica, l'unico modo per avviarne uno o fermarlo consiste nell'interazione con un'attività dell'applicazione (ad esempio con un bottone). La riproduzione di un flusso audio è un esempio di servizio. L'ascolto di un brano, avviato interagendo con i bottoni di un lettore audio, verrà garantito da un servizio anche quando l'utente avvia sul dispositivo una nuova applicazione! La comunicazione con un servizio può avvenire attraverso l'interfaccia che esso fornisce ai programmi;
  • Ricevitori (Broadcast receiver): questo componente notifica gli eventi alle applicazioni, come ad esempio lo stato della batteria, la disponibilità di una risorsa etc... Ogni applicazione, in base alle proprie necessità, può allora servirsi di un preciso numero di ricevitori. Anche questo componente non dispone di un'interfaccia grafica. Va comunque detto che al verificarsi di un evento questo componente può avviare un'attività per la notifica all'utente (mediante la classe NotificationManager). Le notifiche possono anche aggiungere icone nella barra di stato di Android;
  • Fornitori (Content provider): questo componente offre a un'applicazione la possibilità di gestire e condividere dati (ad esempio in un database). Tale possibilità avviene estendendo la classe base ContentProvider (del package android.content) e implementando i metodi per l'inserimento e il recupero dei dati. Le applicazioni non possono tuttavia invocare direttamente i suddetti metodi ma possono accedere ai dati solo attraverso gli oggetti della classe ContentResolver.

martedì 8 febbraio 2011

Xfce 4.8: installazione su Xubunutu 10.04


In attesa di Natty Narwhal (Ubuntu 11.04), dove per Xubuntu si passerà di default ad Xfce 4.8, vediamo come provare con pochi comandi il nuovo ambiente per desktop. Per Ubuntu 10.04:

sudo add-apt-repository ppa:alexx2000/xfce
sudo apt-get update
sudo apt-get install xubuntu-desktop

Il primo comando aggiunge un repository per la distribuzione dei pacchetti (non esistendo ancora un repository ufficiale). E' un'operazione fondamentale per aggiornare in seguito il vostro sistema con nuovi pacchetti già compilati, soprattutto se non volete compilare personalmente il codice sorgente (rilasciato qui). A tale proposito colgo l'occasione per ringraziare alexx2000 per aver svolto il processo di compilazione e pacchettizzazione di Xfce 4.8!
Il secondo comando procede, invece, all'aggiornamento del database locale per i pacchetti software disponibili. Dopo questa operazione il nostro sistema operativo saprà dove reperire i nuovi pacchetti per Xfce.
Il terzo comando, infine, procede all'installazione dell'ambiente desktop. Già dopo il secondo comando potrebbe comparire nell'area di notifica del pannello la disponibilità di nuovi pacchetti. Per Ubuntu 10.10:

sudo add-apt-repository ppa:koshi/xfce-4.8
sudo apt-get update
sudo apt-get install xfce4

Qui, invece, dovete ringraziare koshi! Il changelog di questa versione è davvero lungo, l'elenco completo può essere consultato qui. Thunar, il gestore di file, adesso supporta GVFS (un file system virtuale). Questo faciliterà la condivisione di file e cartelle (attraverso FTP o SSH, ad esempio) poiché avverrà direttamente all'interno di Thunar. E' stata aggiunta una nuova finestra per i processi di copia in parallelo. I dispositivi rimovibili hanno un bottone per l'operazione di umount. Il pannello è stato invece riscritto e la sua gestione è notevolmente migliorata! In Xfce 4.8 disponiamo, adesso, di un nuovo editor per la gestione dei componenti. Il pannello supporta inoltre un livello di trasparenza (possiamo regolarne sia l'opacità a fuoco che quella non a fuoco). Vi invito a consultare questa pagina per vedere le novità grafica di Xfce 4.8. Come sempre Xfce riesce a mantenere quello che promette: un ambiente leggero, veloce e gradevole da utilizzare!
Purtroppo alcuni dei vecchi plugin non sembrano funzionare, come ad esempio gli aggiornamenti meteo, free space checker e generic monitor. Dovendo tenere sotto controllo lo spazio disponibile sul mio Aspire One (che usa un disco SSD da 8GB) ho risolto in parte questo problema installando Conky (con il comando sudo apt-get install conky) e modificando il file /etc/conky/conky.conf in questo modo:

alignment middle_right
background no
border_width 1
cpu_avg_samples 2
default_color white
default_outline_color white
default_shade_color white
draw_borders no
draw_graph_borders yes
draw_outline no
draw_shades no
use_xft yes
xftfont Sans:size=10
override_utf8_locale yes
gap_x 10
gap_y 10
minimum_size 180 0
net_avg_samples 2
no_buffers yes
double_buffer yes
out_to_console no
own_window yes
own_window_class Conky
own_window_transparent yes
own_window_type desktop
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager
stippled_borders 0
update_interval 2.0
uppercase no
use_spacer none
show_graph_scale no
show_graph_range no

TEXT
${color grey}CPU:${color} ${cpu cpu0}% ${alignr}${alignr}${cpubar 8,80 cpu}
${color grey}RAM:${color} $mem/$memmax ($memperc%) ${alignr}${membar 8,80}
${color grey}SWAP:${color} $swap/$swapmax ($swapperc%) ${alignr}${swapbar 8,80}
${color grey}SSD:${color} ${fs_free /root}/${fs_size /root} ($fs_used_perc%) ${alignr}${fs_bar 8,80 /}

${color grey}Download:${color} ${downspeedf wlan0} KB/s
${alignc}${downspeedgraph wlan0 25,200}
${color grey}Upload:${color} ${upspeedf wlan0} KB/s
${alignc}${upspeedgraph wlan0 25,200}