Comment utiliser LiveData avec Realm

Si vous êtes un développeur Android et ne vivez plus comme un sou depuis Google IO’17, vous avez certainement été témoin de beaucoup d’enthousiasme et de nombreux billets de blog concernant les composants d’architecture Android.

La puissance et l’utilité de ces nouveaux composants (ViewModel, Lifecycle, LiveData et Room) suscitent en effet de l’enthousiasme.

Live Data Streams

De mon point de vue, LiveData est la partie la plus excitante de la gamme. C’est génial de voir Google adopter maintenant le concept de données en direct, à mise à jour automatique. C’est également formidable de voir comment LiveData a été intégré dans le nouvel ORM (salle) SQLite.

Cela permet de voir immédiatement la puissance de LiveData, mais ce que j'aime le plus dans la conception de LiveData, c'est que Google l'a rendu générique et qu'il est ouvert aux développeurs pour qu'ils puissent utiliser LiveData dans de nombreux autres cas d'utilisation, tels que:

  • Gestion de l'état du réseau et sensibilisation
  • Renvoi de LiveData avec modification
  • Gestion de l'état des applications

Domaine + LiveData

La nature flexible de LiveData lui permet d’être facilement intégrée à d’autres bibliothèques tierces! En tant qu’ingénieur chez Realm, c’est très excitant pour moi car cela signifie que je peux envelopper RealmResults en tant que LiveData et l’utiliser comme tout autre élément de LiveData.

Cela présente au moins deux avantages supplémentaires.

Cela permet aux développeurs de réagir encore plus facilement aux modifications de données, car ils ne sont plus obligés d'enregistrer un changeListener pour RealmResults dans leur méthode Activities onStart () et de l'annuler de l'enregistrement onStop (). Cela peut plutôt se produire automatiquement avec Realm-LiveData lorsque l'activité propriétaire commence et cesse de l'observer.

Le deuxième avantage est que cela permet à RealmResults de participer aux transformations LiveData. Les transformations sont intéressantes car elles vous permettent de transformer n'importe quel LiveData de quelque chose de très spécifique, comme LiveData , sur votre couche Repository ou ViewModel, en quelque chose de totalement agnostique de la source sous-jacente, tel que LiveData sur la couche d'activité. Vous obtenez cela sans renoncer à la nature de mise à jour automatique en direct de Realm. Cela permet d'isoler les différentes couches de votre application, ce qui facilite leur composition, leur mise à jour et leur test.

Commencer

Pour un guide complet et un exemple de projet sur la façon d'intégrer les composants d'architecture dans Realm, consultez cet autre article que j'ai écrit, mais cet exemple rapide devrait vous donner une idée générale pour commencer.

1. Créez un wrapper LiveData pour vos RealmResults.

// Ceci fonctionne pour les résultats de n'importe quel RealmModel de votre projet
Classe publique RealmLiveData  étend LiveData > {
résultats de domaine  privés;
    final final privé RealmChangeListener > listener =
        new RealmChangeListener > () {
            @Passer outre
            onChange public void (RealmResults  results) {
                setValue (résultats);
            }
    };
    public RealmLiveData (RealmResults  realmResults) {
        résultats = realmResults;
    }
    @Passer outre
    void protected onActive () {
        results.addChangeListener (écouteur);
    }
    @Passer outre
    void protégé onInactive () {
        results.removeChangeListener (écouteur);
    }
}

2. Utilisez-le pour envelopper les RealmResults exposés à partir de votre couche Realm Dao ou Repository.

public RealmLiveData  findLoansByNameAfter (String userName, Date after) {
    return asLiveData (realm.where (Loan.class)
            .like ("user.name", nom d'utilisateur)
            .greaterThan ("endTime", après)
            .findAllAsync ());
    // Async exécute l'extraction du thread principal et retourne
    // résultats en tant que LiveData retour sur le principal.
}

3. Enfin, utilisez-le comme tout autre LiveData de votre ViewModel, en le mappant à quelque chose de plus générique pour votre couche d'activité et abonnez-vous à celui-ci à partir de votre activité.

// ViewModel
Classe publique LoanViewModel étend ViewModel {
    royaume privé;
    
    prêts LiveData  publics;
    // Activité abonnée à LiveData 
    private void subscribeToMikesLoansSinceYesterday () {
        RealmLiveData  loan = loanDao (royaume)
                 .findLoansByNameAfter ("Mike", getYesterdayDate ());
        prêts = Transformations.map (prêts, nouvelle fonction () {...});
    }
    ...
}
// activité
Classe publique LoanActivity étend LifecycleActivity {
  
    Void protégé onCreate (Bundle savedInstanceState) {
        ...
        viewModel.loans.observe (this, nouvel observateur  () {
            public void onChanged (Résultat de la chaîne) {
                updateUI (résultat)
            }
        });
       ...
    }
   ...
}

4. (Facultatif) Saupoudrez un peu de Kotlin et c’est comme si les composants d’architecture Android étaient là depuis le début!

// Utilisé comme
// realm.loanDao () dans Kotlin
// loanDao (royaume) en Java
Realm.loanDao (): LoanDao = LoanDao (ceci)
// Utilisé comme
// realmResults.asLiveData () dans Kotlin
// new RealmLiveData (realm) en Java
fun  RealmResults  .asLiveData () = RealmLiveData  (this)

Impact des composants d'architecture

Cela signifie pour les développeurs qui aiment Realm pour son API simple, son système de notification enrichi et sa synchronisation de données en temps réel sur tous les appareils, que toutes les fonctionnalités d'Android Architecture Components, ViewModels, Lifecycle, LiveData et même l'accès aux données encapsulées via DAO sont disponibles. sans renoncer aux fonctionnalités qu'ils ont appris à aimer!