2015-09-12 4 views
6

Vedo questo codice di esempio nella documentazione di realm java.Notifiche Realm.io [Java] - Come ascoltare le modifiche solo in determinate tabelle?

public class MyActivity extends Activity { 
    private Realm realm; 
    // A reference to RealmChangeListener needs to be held to avoid being 
    // removed by the garbage collector. 
    private RealmChangeListener realmListener; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     realm = Realm.getDefaultInstance(); 
     reamlListener = new RealmChangeListener() { 
     @Override 
     public void onChange() { 
      // ... do something with the updates (UI, etc.) ... 
     }}; 
     realm.addChangeListener(realmListener); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     // Remove the listener. 
     realm.removeChangeListener(realmListener); 
     // Close the realm instance. 
     realm.close(); 
    } 
} 

Ho alcuni schemi di database contengono diverse tabelle. I dati cambiano sempre in queste tabelle, ma ho solo l'unica tabella di cui ho bisogno per ascoltare e aggiornare l'interfaccia utente relativa a questa tabella. Non voglio controllare se questo cambiamento in Realm era esattamente nella tabella ricercata dopo ogni piccolo aggiornamento in qualsiasi altro Realm Objects. Quali best practice puoi suggerire?

risposta

3

Fino a quando Realm non ha notifiche dettagliate, implementerò il mio sistema di notifica utilizzando ContentObserver, RxJava o le proprie interfacce Observer.

2

Come detto Christian RxJava può essere d'aiuto. Anche se, naturalmente, è piuttosto un concetto che potrebbe richiedere importanti cambiamenti nel codice rispetto alla soluzione concreta e rapida del problema. In ogni caso, il modello di repository per l'accesso al nostro database è una buona pratica. È possibile utilizzare il proprio livello per accedere allo Realm. In questo caso è possibile controllare la query su Realm e notificare agli osservatori se i dati sono stati modificati.

public interface RealmRepository { 
      <T> Observable<T> get(Class clazz, Func1<RealmQuery, RealmQuery> predicate); 
      void storeObject(Class clazz, JSONObject jsonObject); 
      void storeObjects(Class clazz, JSONArray jsonArray); 
      <T> Observable<T> update(Class clazz, Action0 action); 
     } 

L'utilizzo del repository dell'interfaccia Realm consente di controllare tutte le richieste.

Ora si otterrà l'oggetto Observable<T> e si può notificare se i dati sono stati modificati.

public class RealmRepositoryImpl implements RealmRepository { 

    Realm realm; 
    RealmQueryableCollection realmQueryCollection; 

    public RealmRepositoryImpl(Realm realm) { 
     this.realm = realm; 
     this.realmQueryCollection = new RealmQueryableCollection(); 
    } 

    @Override 
    public <T> Observable<T> get(Class clazz, Func1<RealmQuery, RealmQuery> predicate) { 
     BehaviorSubject<T> behaviorSubject = BehaviorSubject.create((T) getInner(clazz, predicate)); 
     realmQueryCollection.add(clazz, predicate, behaviorSubject); 
     return behaviorSubject; 
    } 

    public <T extends RealmObject> RealmResults<T> getInner(Class clazz, Func1<RealmQuery, RealmQuery> predicate) { 
     RealmQuery query = realm.where(clazz); 
     if (predicate != null) 
      query = predicate.call(query); 
     return query.findAll(); 
    } 

    @Override 
    public void storeObject(Class clazz, JSONObject jsonObject) { 
     realm.beginTransaction(); 
     realm.createOrUpdateObjectFromJson(clazz, jsonObject); 
     realm.commitTransaction(); 
     notifyObservers(clazz); 

    } 

    @Override 
    public void storeObjects(Class clazz, JSONArray jsonArray) { 
     realm.beginTransaction(); 
     realm.createOrUpdateAllFromJson(clazz, jsonArray); 
     realm.commitTransaction(); 
     notifyObservers(clazz); 
    } 


    @Override 
    public <T> Observable<T> update(Class clazz, Action0 action) { 
     return (Observable<T>) Observable.create(subscriber -> { 
      realm.beginTransaction(); 
      action.call(); 
     }).doOnNext(o -> { 
      realm.commitTransaction(); 
      notifyObservers(clazz); 
     }); 
    } 

    private void notifyObservers(Class clazz) { 
     Observable.from(realmQueryCollection.getQuerables(clazz)) 
       .subscribe(realmQuerable -> 
         realmQuerable.getSubject().onNext(getInner(clazz, realmQuerable.getPredicate()))); 
    } 
} 

Quando make get query basta salvare entità (tabella), predicato (bello rx.functions.Func1) e soggetti. Quando cambierai i dati nel Realm puoi ottenere i dati modificati con il predicato salvato e notificare le modifiche a tutti gli osservatori.

Esempio get query

public Observable<List<Event>> getEvents() { 
     return realmRepository.get(Event.class, predicate -> predicate 
         .equalTo("category", "Art") 
         .or() 
         .equalTo("category", "Music")); 
    } 

A mio parere un approccio reattivo è una soluzione naturale a questo problema.

Codice di esempio completo su GitHub puoi provare a giocare con l'esempio. Al momento non è una soluzione completa (nessuna notifica di cancellazione, ecc.), Ma piuttosto un'idea.

+0

Grazie mille! Ora quando capisco rxJava la tua risposta è geniale! –

+0

Fantastico! forse sarai interessante chat gitter su RxJava bit.ly/andr-rx (russian lang) – Alexandr