Le basi di Android

Come funziona un'applicazione lato teorico.

I componenti principali

In questo articolo andiamo a vedere la base strutturale di una applicazione Android, quindi tutti quei componenti fondamentali di cui un'app è formata. Entrando subito nel vivo, andiamo ad elencare cinque caratteristiche principale che permettono ad un'applicazione di esistere:

  • Activity:
    Un’Activity è un’interfaccia utente. Ogni volta che si usa un’app generalmente si interagisce con una o più “pagine” mediante le quali si consultano dati o si immettono input. Ovviamente la realizzazione di Activity è il punto di partenza di ogni corso di programmazione Android visto che è il componente con cui l’utente ha il contatto più diretto.
  • Service:
    Un Service svolge un ruolo, se vogliamo, opposto all’Activity. Infatti rappresenta un lavoro – generalmente lungo e continuato – che viene svolto interamente in background senza bisogno di interazione diretta con l’utente. I Service hanno un’importanza basilare nella programmazione proprio perchè spesso preparano i dati che le activity devono mostrare all’utente permettendo una reattività maggiore nel momento della visualizzazione.
  • Content Provider:
    Un Content Provider nasce con lo scopo della condivisione di dati tra applicazioni. Questi componenti permettono di condividere, nell’ambito del sistema, contenuti custoditi in un database, su file o reperibili mediante accessi in Rete. Tali contenuti potranno essere usati da altre applicazioni senza invadere lo spazio di memoria.
  • Broadcast Receiver:
    Un Broadcast Receiver è un componente che reagisce ad un invio di messaggi a livello di sistema – appunto in broadcast – con cui Android notifica l’avvenimento di un determinato evento, ad esempio l’arrivo di un SMS o di una chiamata o sollecita l’esecuzione di azioni. Questi componenti come si può immaginare sono particolarmente utili per la gestione istantanea di determinate circostanze speciali.
  • Intent:
    Molto importante ricordare che un componente può attivarne un’altra mediante apposite invocazioni di sistema. Questa intenzione viene codificata con un Intent utilizzabile come normale classe Java ma che sottintende un potentissimo strumento di comunicazione di Android. In pratica un componente può richiedere l’esecuzione di un’azione da parte di un altro componente. Gli utilizzi più comuni ricadono in queste tre casistiche: avviare un’Activity, avviare un Service e inviare un messaggio in broadcast che può essere ricevuto da ogni applicazione.

Il file Manifest.xml

    Ogni applicazione Android dev’essere accompagnata da un file chiamato AndroidManifest.xml nella sua cartella principale. Il Manifest raccoglie informazioni basilari sull’app, informazioni necessarie al sistema per far girare qualsiasi porzione di codice della stessa. Tra le altre cose il Manifest presente in ciascuna app del Play Store si occupa delle seguenti cose:

  • Assegna un nome al package Java dell’applicazione, che è anche un identificatore univoco della stessa.
  • Descrive le componenti dell’applicazione (attività, servizi, receiver, provider, ecc.), nomina le classi e pubblica le loro “competenze”.
  • Determina quali processi ospiteranno componenti dell’applicazione.
  • Dichiara i permessi dell’app e i permessi necessari alle altre app per interagire con la stessa (accesso alla rete, bluetooth, allarmi, vibrazioni, accesso ai file, geolocalizzazione, calendario, attività telefoniche, rubrica e molti altri ancora).
  • Dichiara il livello minimo di API Android che l’app richiede.
  • Elenca le librerie necessarie all’app.

I Layout

Dopo aver chiarito questi concetti primari passiamo ai diversi tipi di layout. Android permette la creazione di interfacce sia procedurali sia dichiarative: possiamo creare un’interfaccia utente completamente in codice Java (metodo procedurale) oppure possiamo creare l’interfaccia utente attraverso un descrittore XML (metodo dichiarativo). Android inoltre permette anche un approccio ibrido, in cui si crea un’interfaccia in modo dichiarativo e la si controlla e specifica in modo procedurale (si richiama il descrittore XML da codice e si continua a lavorare da lì). Nella prassi, su Android un layout viene progettato in XML, in una modalità che ricorda molto l’uso di HTML per le pagine web. Ciò è particolarmente apprezzato da tutti quei programmatori che provengono da esperienze professionali o percorsi didattici nel settore.
Detto questo, i layout si differenziano in:

  • Linear Layout:
    contiene un insieme di elementi che distribuisce in maniera sequenziale dall’alto verso il basso (se definito con orientamento verticale) o da sinistra a destra (se ha orientamento orizzontale, il valore di default). È un layout molto semplice e piuttosto naturale per i display di smartphone e tablet.
  • Table Layout:
    altro layout piuttosto semplice, inquadra gli elementi in una tabella e quindi è particolarmente adatto a mostrare strutture regolari suddivise in righe e colonne come form o griglie. È piuttosto semplice da usare e ricorda molto le tabelle HTML nelle pagine web con i ben noti tag <table> <tr> <td>.
  • Relative Layout:
    sicuramente il più flessibile e moderno. Adatto a disporre in maniera meno strutturata gli elementi, ricorda un po’ il modo di posizionare <div> flottanti nelle pagine web. Essendo “relative” gli elementi si posizionano in relazione l’uno all’altro o rispetto al loro contenitore, permettendo un layout fluido che si adatta bene a display diversi.
  • Frame Layout:
    viene utilizzato quando vi si deve ospitare un unico elemento, in questo caso il Fragment, di cui andremo a parlarne successivamente.
  • Absolute Layout:
    è un layout deprecato ma è giusto spendere qualche parola a riguardo: consente di specificare l'esatta posizione degli elementi figli.
  • Grid Layout:
    E' un layout che posiziona i suoi figli in una griglia rettangolare. Questa griglia è composta da un set di infinite linee che separano i contenuti all'interno di apposite celle.
  • Constraint Layout:
    Questo layout è il più recente in assoluto ed è stato creato appositamente per creare delle interfacce utente dinamiche senza l’utilizzo di layout annidati. Permette di creare layout grandi e complessi con una gerarchia di viste piatte. È simile al RelativeLayout in quanto tutte le visualizzazioni sono disposte in base alle relazioni tra le viste di pari livello e il layout principale, ma è più flessibile e più facile del RelativeLayout.

I Fragment

I Fragment costituiscono senz’altro uno dei più importanti elementi per la creazione di una interfaccia utente Android moderna. Il loro ruolo a partire da Android 3.0 è diventato preponderante tanto che ormai rappresentano una delle conoscenze più importanti per il programmatore. Un Fragment è una porzione di Activity. Ma si faccia attenzione a comprenderne bene il ruolo. Non si tratta solo di un gruppo di controlli o di una sezione del layout. Può essere definito più come una specie di sub-activity con un suo ruolo funzionale molto importante ed un suo ciclo di vita. Prima di tutto un Fragment non può vivere senza un’Activity. Tipicamente nei nostri programmi creeremo più Fragments che si alterneranno nel layout mentre di Activity ne sarà sufficiente una (ma possono essere anche di più).

Il ciclo di vita di una Activity

Un'immagine vale più di mille parole:

ciclo di vita activity
Con questa immagine si intende una catena di stati che l’Activity attraversa durante la sua vita. Buona parte di questi sono indotti dal sistema operativo, che nel rispetto di un corretto utilizzo delle risorse gestisce l’Activity in base alle operazioni svolte dall’utente, decidendo eventualmente di distruggerla quando la considera un consumo inutile di memoria. Quando un’activity va in esecuzione per interagire direttamente con l’utente vengono obbligatoriamente invocati tre metodi:

  • onCreate: l’activity viene creata. Il programmatore deve assegnare le configurazioni di base e definire quale sarà il layout dell’interfaccia;
  • onStart: l’activity diventa visibile. È il momento in cui si possono attivare funzionalità e servizi che devono offrire informazioni all’utente;
  • onResume: l’activity diventa la destinataria di tutti gli input dell’utente.

  • Android pone a riposo l’activity nel momento in cui l’utente sposta la sua attenzione su un’altra attività del sistema, ad esempio apre un’applicazione diversa, riceve una telefonata o semplicemente – anche nell’ambito della stessa applicazione – viene attivata un’altra Activity. Anche questo percorso, passa per tre metodi di callback:

  • onPause (l’inverso di onResume) notifica la cessata interazione dell’utente con l’activity;
  • onStop (contraltare di onStart) segna la fine della visibilità dell’activity;
  • onDestroy (contrapposto a onCreate) segna la distruzione dell’activity.

Il Threading

I thread costituiscono un filone di esecuzione interno ad un’applicazione. In pratica, sono la vera anima operativa di un programma a runtime. Solitamente un qualunque software – nel mondo mobile e non – vede contemporaneamente attivi più thread. Ognuno di essi svolgerà in maniera a sé stante una sequenza di operazioni, come se fosse “un programma nel programma”. Si consideri che quando si utilizza un’Activity il thread principale dell’applicazione si occupa prevalentemente di gestire i messaggi relativi al funzionamento dell’interfaccia utente. Svolgere in questo stesso thread operazioni presumibilmente “lente” come ad esempio la lettura e scrittura da file, il prelevamento di dati da un database, il caricamento di immagini rischierebbe di rendere poco reattiva la UI. Conseguenza di ciò sarebbe una user experience non troppo gradevole che porterebbe l’utente a sostituire la nostra app con altre molto più scattanti. Operazioni “lente” dovrebbero essere preferibilmente svolte su thread secondari, detti anche worker thread, e possibilmente devono essere svolte in maniera asincrona (AsyncTask), ovvero dovrebbero agire in background contemporaneamente e parallelamente con i thread principali.

Le risorse

Se si dà uno sguardo ad un qualsiasi progetto per Android si può vedere che la cartella "res" conta diverse sottocartelle i cui nomi non sono affatto casuali. Tra quelle di più comune utilizzo, troviamo:

  • layout:
  • conterrà l’architettura grafica dei componenti dell’interfaccia utente. Sono definiti in XML in una maniera simile a come viene usato HTML per strutturare le pagine web;
  • values:
  • conterrà stringhe, colori, dimensioni e altre tipologie di valori che potranno essere usate in ulteriori risorse o nel codice Java. Importante notare che questi valori costituiranno il contenuto di appositi tag XML (<string>, <dimen>, etc.) raggruppati in files dal nome solitamente indicativo: strings.xml, dimens.xml, colors.xml e via dicendo. Tali nomi sono frutto di pura convenzione ma il programmatore può scegliere liberamente come chiamarli;
  • drawable:
  • sono immagini nei formati più comuni o, cosa che può stupire, configurate in XML;
  • mipmap:
  • sono immagini che costituiscono l’icona dell’applicazione, quella con cui viene lanciata da sistema operativo. Un tempo erano collocate tra i drawable ma successivamente gli è stata dedicata una sezione a parte tra le risorse.

Fine dei giochi.

Ho deciso di terminare qui l'articolo consapevoli del fatto che esiste una enorme vastità di concetti ancora da affrontare come: il Material Design, l'interfaccia grafica (GUI), gli hardware ed i sensori, le animazioni, la parte multimediale e sociale, l'ambiente di sviluppo Android Studio e molto altro ancora. Ci saranno sicuramente altri articoli a riguardo, tuttavia invito chiunque a soddisfare la propria sete di curiosità approfondendo tutti questi argomenti affrontati e non. Dove? Beh, sicuramente non c'è niente di meglio che consultare la documentazione ufficiale Android cliccando QUI.

A presto, GG-CREATOR.


« Articolo successivo:
I migliori widgets & plugins
» Articolo precedente:
I Social Networks