Realm.io [Java] 通知 - 如何只监听某些 Table 中的变化?
Realm.io [Java] notifications - How to listen for changes only in certain Table?
我在领域 java 文档中看到了这个示例代码。
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();
}
}
我有一些数据库架构包含多个 table。这些 table 中的数据总是在变化,但我只有一个 table 我需要收听并刷新与此 table 相关的 UI。我不想检查 Realm 中的这种变化是否在任何其他 Realm 对象的任何小更新之后完全符合需要 table。
您可以建议哪些最佳做法?
在 Realm 具有细粒度通知之前,我会使用 ContentObserver、RxJava 或您自己的 Observer 接口来实现我自己的通知系统。
正如克里斯蒂安所说 RxJava 可以提供帮助。虽然当然是一个可能需要对代码进行重大更改的概念,而不是对问题的具体和快速解决方案。在任何情况下,用于访问我们数据库的存储库模式都是很好的做法。您可以使用自己的层访问 Realm
。在这种情况下,您可以控制对 Realm
的查询并在数据更改时通知观察者。
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);
}
使用 Realm 接口存储库可以确保您控制所有请求。
现在您将获得 Observable<T>
对象,并且可以在数据更改时发出通知。
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())));
}
}
当生成 get query
时,您只需保存实体 (table)、谓词 (nice rx.functions.Func1
) 和主题。当您更改 Realm
中的数据时,您可以使用保存的谓词获取更改的数据并通知所有观察者更改。
示例get query
public Observable<List<Event>> getEvents() {
return realmRepository.get(Event.class, predicate -> predicate
.equalTo("category", "Art")
.or()
.equalTo("category", "Music"));
}
在我看来,反应式方法是解决此问题的自然方法。
GitHub 上的完整示例代码您可以尝试使用该示例。目前它不是完整的解决方案(没有通知取消订阅等),而只是一个想法。
我在领域 java 文档中看到了这个示例代码。
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();
}
}
我有一些数据库架构包含多个 table。这些 table 中的数据总是在变化,但我只有一个 table 我需要收听并刷新与此 table 相关的 UI。我不想检查 Realm 中的这种变化是否在任何其他 Realm 对象的任何小更新之后完全符合需要 table。 您可以建议哪些最佳做法?
在 Realm 具有细粒度通知之前,我会使用 ContentObserver、RxJava 或您自己的 Observer 接口来实现我自己的通知系统。
正如克里斯蒂安所说 RxJava 可以提供帮助。虽然当然是一个可能需要对代码进行重大更改的概念,而不是对问题的具体和快速解决方案。在任何情况下,用于访问我们数据库的存储库模式都是很好的做法。您可以使用自己的层访问 Realm
。在这种情况下,您可以控制对 Realm
的查询并在数据更改时通知观察者。
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);
}
使用 Realm 接口存储库可以确保您控制所有请求。
现在您将获得 Observable<T>
对象,并且可以在数据更改时发出通知。
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())));
}
}
当生成 get query
时,您只需保存实体 (table)、谓词 (nice rx.functions.Func1
) 和主题。当您更改 Realm
中的数据时,您可以使用保存的谓词获取更改的数据并通知所有观察者更改。
示例get query
public Observable<List<Event>> getEvents() {
return realmRepository.get(Event.class, predicate -> predicate
.equalTo("category", "Art")
.or()
.equalTo("category", "Music"));
}
在我看来,反应式方法是解决此问题的自然方法。
GitHub 上的完整示例代码您可以尝试使用该示例。目前它不是完整的解决方案(没有通知取消订阅等),而只是一个想法。