Per illustrare come funziona event bus, riprendiamo l'esempio visto nella sezione precedente e ripensiamolo con l'uso
del bus di eventi:
Come si vede dal sequence diagram, è stata introdotta un'altra line: il bus di eventi chiamato EventBus. A questo punto è possibile fare alcune considerazioni:
- i componenti sono disaccoppiati: nell'esempio iniziale l'activity
MainActivity
sapeva che doveva
invocare il serviceMyService
. Con il bus di eventi l'activity segnala al bus di eventi, e il service riceve l'evento dal bus di eventi. Non c'è una comunicazione
diretta tra i due componenti. - La gestione della comunicazione tra componenti, in termini di codice da scrivere, è più semplice.
- Un evento può essere propagato a più componenti semplicemente aggiungendo dei subscriber con l'annotazione
@Subscribe
. Se ad esempio si volesse
introdurre un altro service chiamatoSecondService
per svolgere un'altra attività
come conseguenza dell'emissione di un evento di tipo Task start, il sequence diagram sopra illustrato diventerebbe:
Nell'activity per generare un evento di tipo ActivityEvent
è sufficiente eseguire il seguente codice:
EventBus.getDefault().post(new ActivityEvent());
Lato Service per poter sottoscrivere lo stesso evento è sufficiente agganciare la registrazione del
componente su event bus al suo stesso ciclo di vita:
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEvent(ActivityEvent event){
..
MessageEvent message=new MessageEvent();
message.message="Operazione in background terminata!";
EventBus.getDefault().post(message);
}
Da notare che alla fine della sottoscrizione dell'evento, viene inviato un altro messaggio di tipo
MessageEvent
con un codice molto simile a quanto già visto in precedenza.
EventBus: sticky events
Una caratteristica che e' bene citare di EventBus è la possibilita' di poter gestire i cosidetti Sticky
Events, ovvero degli eventi
che rimangono nella coda degli eventi anche dopo esser stati inviati. A dire il vero viene tenuto solo l'ultimo
evento di un determinato
tipo.
Grazie a questi tipi di eventi e' possibile fare in modo che tutti i subscriber ricevano, una volta registrati
per un particolare Sticky Event, l'ultimo evento di quel tipo. L'emissione di tali messaggi e' molto simile a quella di un qualunque messaggio,
tranne per il fatto che vengono innescati
mediante il metodo postSticky
EventBus.getDefault().postSticky(new StatusEvent("Servizio STARTED"));
I subscriber degli eventi di tipo sticky sono cosi' definiti:
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(StatusEvent event) {
textField.setText(event.message);
}
Si puo' rimuovere manualmente uno sticky event con un codice simile a quello sotto riportato:
StatusEvent stickyEvent = EventBus.getDefault().removeStickyEvent(StatusEvent.class);
// Verifichiamo se e' stato in effetti rimosso qualcosa
if(stickyEvent != null) {
// ASSERT: era presente un evento
}
Conclusioni
Al fine di evitare inutili grattacapi nell'uso di EventBus: una volta inserita la libreria nel proprio progetto, se si prova ad eseguire la compilazione del progetto e non
ci sono subscriber
verrà generato un errore. Ovviamente questo è un finto problema: dopo l'inserimento del primo subscriber l'errore scomparirà.
EventBus è disponibile come progetto open source su Github.