Realm.io notificaciones – ¿Cómo escuchar los cambios sólo en cierto cuadro?
Veo este código de ejemplo en la documentación de realm 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(); } }
Tengo un esquema de base de datos que contiene varias tablas. Los datos siempre están cambiando en estas tablas pero solo tengo una tabla que necesito para escuchar y actualizar la interfaz de usuario relacionada con esta tabla. No quiero comprobar si estos cambios en Realm estaban exactamente en la tabla deseada después de cualquier pequeña actualización en cualquier otro Realm Objects. ¿Qué prácticas recomendadas puedes sugerir?
- Creación de apklibs con maven e InteliJ
- ¿Cómo obtengo una variable de un bloque try / catch?
- ¿Cómo escribir el "al poder" y algún texto como se muestra en Java o Android?
- Adaptador de matriz de Android con ArrayList y ListView no se actualizan cuando se cambia el arraylist
- ¿Hay una manera de encontrar los temporizadores de ejecución en java?
- Deserialización de Gson de List <String> en realmList <RealmString>
- Viewport ajusta el ancho de la pantalla y las grandes imágenes
- Comenzando a programar en lenguajes dinámicos en Android ((J) Ruby, Clojure ...)
- ¿Por qué GSON poner un punto decimal y un cero después de todos mis números JSON que originalmente no contienen ningún decimal?
- Android java, obtener más uso de memoria permitido
- No se puede resolver el símbolo de Android - Android app - intelliJ
- Singletons vs. Contexto de la aplicación en Android?
- Intentando ejecutar un proyecto de Android en IntelliJ: Error: Terminación del proceso de compilación anormal: Error: Esta instancia de Java no admite una JVM de 32 bits.
Hasta que Realm tenga notificaciones detalladas, implementaría mi propio sistema de notificación utilizando ContentObserver, RxJava o sus propias interfaces de Observer.
Como dijo Christian RxJava es puede ayudar. Aunque por supuesto es más bien un concepto que puede requerir grandes cambios en el código que la solución concreta y rápida para el problema. En cualquier caso, el patrón de repositorio para el acceso a nuestra base de datos es una buena práctica. Puede usar su propia capa para acceder al Realm
. En este caso, puede controlar la consulta al Realm
y notificar a los observadores si los datos han cambiado.
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); }
El uso del repositorio de interfaz Realm le permite asegurarse de que controla todas las solicitudes.
Ahora obtendrá el objeto Observable<T>
y puede notificar si los datos han cambiado.
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()))); } }
Cuando se get query
, solo guarda entidad (tabla), predicado ( rx.functions.Func1
agradable) y subject. Cuando cambie los datos en el Realm
, puede obtener datos modificados con el predicado guardado y notificar acerca de los cambios de todos los observadores.
Ejemplo get query
public Observable<List<Event>> getEvents() { return realmRepository.get(Event.class, predicate -> predicate .equalTo("category", "Art") .or() .equalTo("category", "Music")); }
En mi opinión, un enfoque reactivo es una solución natural a este problema.
Código de ejemplo completo en GitHub puedes intentar jugar con el ejemplo. Por el momento no es una solución completa (no hay anulación de notificación, etc), sino más bien una idea.
- Android: La barra de acción predeterminada se está poblando mientras se carga la aplicación
- Diferencia entre restartLoader y onContentChanged