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.