2015-09-12 11 views
6

Ich sehe diesen Beispielcode in Realm-Java-Dokumentation.Realm.io [Java] -Benachrichtigungen - Wie kann nur in bestimmten Tabellen nach Änderungen gesucht werden?

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(); 
    } 
} 

Ich habe einige Datenbankschema enthalten mehrere Tabellen. Die Daten ändern sich immer in diesen Tabellen, aber ich habe nur die eine Tabelle, die ich hören und die Benutzeroberfläche für diese Tabelle aktualisieren muss. Ich möchte nicht überprüfen, ob diese Änderungen in Realm genau in der gewünschten Tabelle nach irgendwelchen kleinen Aktualisierungen in anderen Realm-Objekten waren. Welche Best Practices können Sie vorschlagen?

Antwort

3

Bis Realm feingranulare Benachrichtigungen hat, würde ich mein eigenes Benachrichtigungssystem entweder mit ContentObserver, RxJava oder eigenen Observer-Schnittstellen implementieren.

2

Wie gesagt, kann Christian RxJava helfen. Dies ist natürlich ein Konzept, das größere Änderungen im Code erfordert als eine konkrete und schnelle Lösung des Problems. In jedem Fall ist das Repository-Muster für den Zugriff auf unsere Datenbank eine gute Praxis. Sie können eine eigene Ebene für den Zugriff auf die Realm verwenden. In diesem Fall können Sie die Abfrage an die Realm steuern und Beobachter benachrichtigen, wenn sich die Daten geändert haben.

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); 
     } 

Mit dem Realm Interface Repository können Sie sicherstellen, dass Sie alle Anfragen kontrollieren.

Jetzt erhalten Sie Observable<T> Objekt und kann benachrichtigen, wenn Daten geändert haben.

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()))); 
    } 
} 

Wenn make get query Sie gerade Einheit speichern (Tabelle), Prädikat (schöne rx.functions.Func1) und Subjekt. Wenn Sie die Daten in der Realm ändern, können Sie geänderte Daten mit gespeicherten Prädikat erhalten und über Änderungen alle Beobachter benachrichtigen.

Beispiel get query

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

Meiner Meinung nach einem reaktiver Ansatz ist eine natürliche Lösung für dieses Problem.

Volle Beispielcode auf GitHub können Sie versuchen, mit dem Beispiel zu spielen. Im Moment ist es keine vollständige Lösung (keine Benachrichtigung abbestellen, etc), sondern nur eine Idee.

+0

Vielen Dank! Jetzt, wenn ich rxJava verstehe, bist du brillant! –

+0

Cool! vielleicht wirst du ein interessanter Gitter-Chat über RxJava sein bit.ly/andr-rx (russian lang) – Alexandr

Verwandte Themen