Notifications Realm.io [Java] - How to listen to changes only in a specific table?

I see this sample code in the Java documentation.

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

I have a database schema containing multiple tables. The data always changes in these tables, but I only have one table that I need to listen to and update the interface associated with this table. I do not want to check whether these changes in Realm are in the desired table after any small update in any other Realm objects. What recommendations can you offer?

+6
source share
2 answers

As long as Realm has fine-grained notifications, I would use my own notification system either using ContentObserver, RxJava, or with your own Observer interfaces.

+3
source

As a Christian RxJava said, it can help. Although, of course, this is more a concept that may require major changes in the code than a concrete and quick solution to the problem. In any case, the repository template for accessing our database is good practice. You can use your own layer to access Realm . In this case, you can manage the Realm request and notify observers if the data is changed.

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

Using the Realm interface repository allows you to control all requests.

Now you will get an Observable<T> object and you can notify if the data has changed.

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

When make get query you just save the entity (table), predicate (nice rx.functions.Func1 ) and subject. When you change the data in Realm , you can retrieve the changed data with the saved predicate and notify all observers of the changes.

get query example

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

In my opinion, a reactive approach is a natural solution to this problem.

A complete sample of GitHub code, which you can try to reproduce with an example. At the moment, this is not a complete solution (without notification from a subscription, etc.), but just an idea.

+2
source

All Articles