Android annotations. Meno codice, più leggibilità

A

INDRODUZIONE

Durante la scrittura di applicazioni Android mi è capitato molto spesso di sentirmi frustrato nel dover scrivere alcune parti di codice che risultano prolisse rispetto alle azioni svolte. Un caso di esempio che riporto sempre è quello di un AsyncTask. Per eseguire una singola azione in background siamo costretti a creare una nuova classe (anonima,interna o locale), tutto a discapito della leggibilità del codice.
E’ possibile quindi riuscire a scrivere meno codice e in modo che risulti più leggibile?
Vediamo come Android Annotations può darci una mano a risolvere questo problema.

DEFINIZIONE E OBIETTIVI DI ANDROID ANNOTATIONs

Android Annotations (AA) è un Framework Open Source che si prefigge come obiettivo quello di velocizzare la scrittura e lettura del codice mantenendo semplicità e mantenibilità dello stesso. Sarà infatti possibile eseguire l’inject di View, Servizi, Extra, creare velocemente client REST, classi anonime, ecc….
Innanzi tutto è importante capire come funziona.
Come ci suggerisce il nome, tutto ruota attorno alle Annotations. Per chi non avesse idea di cosa stò parlando può fare riferimento a questo articolo di wikipedia dove viene spiegato molto bene la loro funzione e utilizzo.
Detto questo, quando nel codice compare un’annotation, a compile time, il framework esegue tutto il lavoro sporco al posto nostro generando tutta l’implementazione in una classe (chiamata come la classe originale seguita dal carattere underscore) nella directory di build.
Fin qui il discorso può risultare un po fumoso ma quello che è importante è aver capito a cosa serve e come funziona Android Annotations, ora vediamo con alcuni esempi pratici di chiarirci le idee.

CONFIGURAZIONE

Come di consuetudine per aggiungere la libreria al nostro progetto è sufficiente aprire il file build.gradle del modulo dell’applicazione ( generalmente chiamato app ) e aggiungere le seguenti dipendenze

def AAVersion = 'XXX'
dependencies {
    annotationProcessor "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
}

dove al posto del valore XXX andremo a indicare la versione corrente.
Eseguendo la sincronizzazione delle librerie siamo già in grado di utilizzare il framework. Per tutto quello che riguarda l’approfondimento di come utilizzare la versione di snapshot, i plugin aggiuntivi o qualsiasi altra informazione possiamo fare riferimento alla pagina ufficiale del wiki.

ESEMPIO PRATICO

L’esempio che vi voglio proporre è quello in cui tutti sicuramente abbiamo esperienza. La seguente è una semplice Activity contenente un Button che premuto lancia un AsyncTask che in background compie un’azione ed infine scrive un testo nella TextView, in aggiunta viene anche installato un menu.

Codice classico

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView textView;

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = findViewById(R.id.button);
    }

    @Override
    public void onClick(View v) {
        new MyAsyncTask().execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu_home,menu);
        return super.onCreateOptionsMenu(menu);
    }

    private class MyAsyncTask extends AsyncTask<Void,Void,Void> {

        @Override
        protected Void doInBackground(Void... voids) {
            // Azione in background
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            textView.setText("Ora: " + DateFormat.getDateInstance(DateFormat.LONG).format(Calendar.DATE));
        }
    }
}

Con Android Annotations

@OptionsMenu(R.menu.menu_home)
@EActivity(R.layout.activity_main)
public class MainActivityAA extends AppCompatActivity {

    @ViewById
    TextView textView1;

    @Click
    void buttonClicked() {
        doActionInBackground();
    }

    @Background
    void doActionInBackground() {
        // Azione in background
        updateUi();
    }

    @UiThread
    void updateUi() {
        textView1.setText("Ora: " + DateFormat.getDateInstance(DateFormat.LONG).format(Calendar.DATE));
    }
}

Notevole vero?
Vediamo in dettaglio di capire il codice dell’esempio:
Come detto precedentemente, a compile time, viene generata automaticamente la classe MainActivityAA_ contentente l’implementazione del codice nella directory build. Questa può essere aperta in qualsiasi momento per vederne la sua implementazione che risulterà molto simile a quella del codice originale.

Analisi delle annotations presenti

@OptionsMenu(R.menu.menu_home) Aggiunge il menu_home all’activity, va a sostituire quindi tutto l’override del metodo onCreateOptionsMenu che troveremo implementato nella classe MainActivityAA_

@EActivity(R.layout.activity_main) In questo caso nel metodo onCreate della classe generata verrà aggiunto il codice per inserire il layout all’activity

@ViewById sostituisce il findViewById che viene fatto automaticamente assegnando alla TextView la View con identificativo R.id.textView1

@Click aggiunge alla View con identificativo R.id.button un onClickListener che alla sua attivazione esegue il metodo buttonCLicked()

@Background come è facile intuire esegue tutto il codice del metodo in un task in baskground

@UiThread esegue il task nel main thread dell’applicazione

Questo è solo uno dei tanti esempi che si potrebbero fare sull’utilizzo delle Android Annotations perchè sono davvero tante per i più svariati scopi, un REST client, Service, Broadcast, ecc…
Esistono poi, come integrazione, framework di terze parti per estendere l’utilizzo delle annotations a Orm, DataBinding, Test Unit, ecc…
Tra i più famosi e utilizzati possiamo ricordare

  • OrmLite, un orm appunto semplice e leggero per gestire la persistenza delle classi Java su database.
  • Kotlin, estendendo il loro utilizzo quindi anche con il nuovo linguaggio di programmazione.
  • Otto event bus, un progetto che fornisce l’implementazione di event bus per il dialogo fra activity e fragment o activity e service.

 

CONCLUSIONI

In questo articolo abbiamo visto un piccolo esempio di quello che Android Annotations ci può dare rispetto alla stesura classica del codice in una applicazione Android. Per quanto mi riguarda non ho dubbi nell’affermare che gli obiettivi prefissati sono stati raggiunti in maniera più che eccellente. Il codice risulta meno prolisso e molto più leggibile evitanto di scrivere molte righe superflue apparendo molto più snello.
La cosa molto interessante è l’opportunità di poter visualizzare il codice generato avendo anche la possibilità di entrarne in debug. Considerando che la libreria pesa meno di 150kb e non influisce minimamente sulle performance a runtime non posso far altro che consigliare il suo uso a chiunque perchè non richiede l’utilizzo delle conoscenze di un programmatore esperto contanto poi su un wiki davvero ben fatto, semplice e con le spiegazioni per ogni annotation presente.

A proposito di me

Gianluca Fattarsi

Perito informatico, esperienza come programmatore nell'ambito lavorativo dal lontano 2002. La sua formazione in Java spazia dal Front-End al Back-End con esperienze in gestione database e realizzazione di App Android in Kotlin. Hobby preferiti: Linux, lettura e World of Warcraft.

I nostri Partner

Gli articoli più letti

Articoli recenti

Commenti recenti