Friday 20 December 2013

Gestione di schermi multipli su Android

Con la versione di Android 4.2 (Jelly Bean) è stata introdotta un'interessante novità: la gestione di schermi multipli, ovvero la nostra app può gestire la visualizzazione su una pluralità di schermi (connessi al dispositivo via wifi, oppure collegati con il cavo HDMI).
Per fare questo si utilizza la classe Presentation, che permette di inviduare i diversi display collegati ed assegnare una specifica View a ciascuno di essi.

Ecco dunque il consueto tutorial:
Tutorial - Gestione di schermi multipli su Android

Thursday 19 December 2013

Ottimizzazione del codice Java per Android - parte I

In questo breve tutorial parlerò di un argomento non molto trattato nei manuali ufficiali dedicati alla programmazione per Android. Si tratta di una serie di consigli e trucchi relativi alla ottimizzazione del codice Java per la piattaforma Android, vale a dire come scrivere codice Java che sia il più possibile efficiente, considerando le particolarità del sistema operativo Android.
Come noto, le applicazioni per Android sono scritte in linguaggio Java (codice sorgente). Il codice sorgente è trasformato in byte-code (codice intermedio) da un compilatore, per poi essere interpretato ed eseguito da una Virtual Machine. Nella piattaforma Android la Virtual Machine è rappresentata dalla Dalvik Virtual Machine, sviluppata da Google, una particolare versione della Java Virtual Machine ottimizzata per i dispositivi mobili.

Benché il funzionamento della Dalvik Virtual Machine sia in gran parte assimilabile a quello della Java Virtual Machine, esistono delle differenze sostanziali, che impongono di adottare un diverso approccio nella programmazione Java al fine di ottimizzare le prestazioni delle nostre app. Più precisamente, poiché le nostre app possono girare su una pluralità di dispositivi, alcuni dei quali datati o con scarse risorse hardware, è necessario prestare particolare attenzione alla ottimizzazione del codice.

Ecco dunque la prima parte del tutorial (a breve anche la seconda parte):

Saturday 14 December 2013

Il componente Application

Nelle app Android il componente Application è poco conosciuto ed utilizzato, tuttavia può tornare utile in determinate situazioni.
Application è il componente che sta sopra tutti gli altri, Activity, Service e BroadcastReceiver compresi.
Ogni app Android ha un componente Application: se il programmatore non ne specifica uno, ne viene creato automaticamente uno di default.
Per ottenere un reference a questo componente si usa il comando Context.getApplication().
Siccome il componente Application è unico per ogni app Android, lo si può utilizzare per condividere variabili globali tra i vari componenti della nostra app (ad esempio tra le varie Activity).

Vediamo quindi un esempio di come sfruttare il componente Application per condividere delle variabili globali tra i vari componenti della nostra app. Ogni volta che una variabile globale di Application viene modificata, tutti i componenti (ad es. le varie Activity) riceveranno una notifica.


public class MiaApplication extends Application {
    private ConcurrentHashMap<String, String> variabiliGlobali;
    private Set<AppStateListener> mieiAppStateListeners;

    @Override
    public void onCreate() {
        super.onCreate();

        //chiamato prima della creazione di qualsiasi altro componente  
        variabiliGlobali = new ConcurrentHashMap<String, String>();
                mieiAppStateListeners = Collections.synchronizedSet(newHasSet<AppStateListeners>());
    }

    public String getVariabileGlobale(String chiave) {
        return variabiliGlobali.get(chiave);
    }

    public String rimuoviVariabileGlobale(String chiave) {
        String valore = variabiliGlobali.remove(chiave);
        notificaListeners(chiave, null);
        return valore;
    }

    public void inserisciVariabileGlobale(String chiave, String valore) {
        variabiliGlobali.put(chiave, valore);
        notificaListeners(chiave, valore);
    }   
        public void aggiungiAppStateListener(AppStateListener appStateListener) {
        mieiAppStateListeners.add(appStateListener);
    }

    public void rimuoviAppStateListener(AppStateListener appStateListener) {
        mieiAppStateListeners.remove(appStateListener); 
    }

    private void notificaListeners(String chiave, String valore) {  
        for(AppStateListener appStateListener : mieiAppStateListeners) {
            appStateListener.onStateChanged(chiave, valore);
        }
    }

    public interface AppStateListener { 
        void onStateChanged(String chiave, String valore);
    }
}


Ora che abbiamo definito  la nostra classe personalizzata MiaApplication, dobbiamo specificarla nel file Manifest della nostra app.

<application android:label="@string/app_name"
    android:icon="@drawable/app_icon"
    android:name=".MiaApplication">

<!-- ecc. ecc. -->
</application>


Vediamo ora come utilizzare la nostra classe personalizzata MiaApplication in una ipotetica Activity:

public class MiaActivity extends Activity implements MiaApplication.AppStateListener {
    
    @Override
    protected void onResume() {
        super.onResume();
        MiaApplication miaApplication = (MiaApplication) getApplication();
        miaApplication.aggiungiAppStateListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        MiaApplication miaApplication = (MiaApplication) getApplication();
        miaApplication.rimuoviAppStateListener(this);
    }

    @Override
    public void onStateChanged(String chiave, String valore) {
        //gestire il cambiamento delle variabili globali
    }
}


Naturalmente per aggiungere una variabile globale si userà un'istruzione del tipo:

miaApplication.inserisciVariabileGlobale(chiave, valore);

questo automaticamente chiamerà onStateChanged su tutti i componenti che implementano l'interfaccia MiaApplication.AppStateListener.