Come utilizzare LiveData con Realm

Se sei uno sviluppatore Android e non vivi da una roccia da quando Google IO '17 hai senza dubbio visto molta eccitazione e numerosi post sul blog riguardanti i componenti dell'architettura Android.

C'è davvero molto di cui essere entusiasti riguardo la potenza e l'utilità di questi nuovi componenti (ViewModel, Lifecycle, LiveData e Room).

Flussi di dati in tempo reale

Dal mio punto di vista, LiveData è la parte più eccitante della line-up. È fantastico vedere Google che ora abbraccia il concetto di dati in tempo reale, con aggiornamento automatico. È altrettanto fantastico vedere come hanno integrato LiveData direttamente nel nuovo SQLite ORM (Room).

Questo rende facile vedere subito la potenza di LiveData, ma ciò che amo di più della progettazione di LiveData è che Google ha reso generico e aperto agli sviluppatori l'uso di LiveData per una varietà di altri casi d'uso come:

  • Gestione e consapevolezza dello stato della rete
  • Restituzione di LiveData con Retrofit
  • Gestione dello stato dell'applicazione

Realm + LiveData

La natura flessibile di LiveData consente di integrarlo facilmente anche in altre librerie di terze parti! Come ingegnere in Realm, questo è molto eccitante per me perché significa che posso avvolgere RealmResults come LiveData e usarlo come farei con qualsiasi altro pezzo di LiveData.

Questo ha almeno due vantaggi aggiuntivi.

Rende ancora più facile per gli sviluppatori reagire alle modifiche dei dati in quanto non devono più registrare un changeListener per RealmResults nel loro metodo Activity onStart () e annullare la registrazione su OnStop (). Piuttosto, ciò può accadere automaticamente con Realm-LiveData quando l'attività proprietaria inizia e smette di osservarla.

Il secondo vantaggio è che consente a RealmResults di partecipare alle trasformazioni di LiveData. Le trasformazioni sono eccezionali perché ti consentono di trasformare qualsiasi LiveData da qualcosa di molto specifico, come LiveData , nel tuo repository o ViewModel, in qualcosa di completamente agnostico della fonte sottostante, come LiveData nel livello attività. Ottieni questo senza rinunciare alla natura di aggiornamento automatico in tempo reale di Realm. Ciò mantiene isolati i vari livelli della tua app, facilitando la composizione, l'aggiornamento e il test.

Iniziare

Per una guida pratica completa e un progetto di esempio su come integrare Architecture Components in Realm, dai un'occhiata a questo altro post che ho scritto, ma questo breve esempio dovrebbe darti l'idea generale di iniziare.

1. Crea un wrapper LiveData per RealmResults.

// Funziona per i risultati di qualsiasi RealmModel nel tuo progetto
classe pubblica RealmLiveData  estende LiveData > {
risultati privati ​​RealmResults ;
    privato finale RealmChangeListener > listener =
        nuovo RealmChangeListener > () {
            @Oltrepassare
            public void onChange (risultati RealmResults ) {
                setValue (risultati);
            }
    };
    public RealmLiveData (RealmResults  realmResults) {
        risultati = realmResults;
    }
    @Oltrepassare
    protetto void onActive () {
        results.addChangeListener (ascoltatore);
    }
    @Oltrepassare
    protetto void onInactive () {
        results.removeChangeListener (ascoltatore);
    }
}

2. Usalo per avvolgere RealmResults esposto dal tuo livello Realm Dao o Repository.

public RealmLiveData  findLoansByNameAfter (String userName, Date after) {
    return asLiveData (realm.where (Loan.class)
            .like ("user.name", userName)
            .greaterThan ("endTime", dopo)
            .findAllAsync ());
    // Async esegue il recupero dal thread principale e restituisce
    // risulta come LiveData di nuovo sul main.
}

3. Infine, usalo come faresti con qualsiasi altro LiveData nel tuo ViewModel, mappandolo a qualcosa di più generico per il tuo livello di attività e iscriviti ad esso dalla tua attività.

// ViewModel
classe pubblica LoanViewModel estende ViewModel {
    regno privato;
    
    prestiti pubblici LiveData ;
    // Attività iscritta a LiveData 
    void privato iscrivitiToMikesLoansSinceYesterday () {
        RealmLiveData  prestiti = loanDao (regno)
                 .findLoansByNameAfter ("Mike", getYesterdayDate ());
        loans = Transformations.map (prestiti, nuova funzione () {...});
    }
    ...
}
// Attività
public class LoanActivity estende LifecycleActivity {
  
    protetto void onCreate (pacchetto salvatoInstanceState) {
        ...
        viewModel.loans.observe (this, new Observer  () {
            public void onChanged (Risultato della stringa) {
                updateUI (risultato)
            }
        });
       ...
    }
   ...
}

4. (Opzionalmente) Cospargi un po 'di Kotlin ed è come se Android Architecture Components fosse stato lì tutto il tempo!

// Usare come
// realm.loanDao () in Kotlin
// loanDao (regno) in Java
fun Realm.loanDao (): LoanDao = LoanDao (questo)
// Usare come
// realmResults.asLiveData () in Kotlin
// nuovo RealmLiveData (regno) in Java
fun  RealmResults  .asLiveData () = RealmLiveData  (questo)

Impatto dei componenti dell'architettura

Ciò che questo significa per gli sviluppatori che amano Realm per la sua semplice API, il ricco sistema di notifica e la sincronizzazione dei dati in tempo reale su tutti i dispositivi è che sono disponibili tutte le parti migliori di Android Architecture Components, ViewModels, Lifecycle, LiveData e persino l'accesso incapsulato ai dati tramite DAO senza rinunciare alle funzionalità che hanno imparato ad amare!