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.
Grazie mille! Ora quando capisco rxJava la tua risposta è geniale! –
Fantastico! forse sarai interessante chat gitter su RxJava bit.ly/andr-rx (russian lang) – Alexandr