RealmChangeListener no se llama cuando Realm se actualiza en NotificationListenerService

Estoy haciendo inserciones de Realm en un NotificationListenerService ampliado, como este:

public class NLService extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { // building realmObject here mRealm = Realm.getDefaultInstance(); RealmHelper.saveObj(myRealmObject, mRealm); // mRealm.waitForChange(); / mRealm.refresh(); mRealm.close(); } } public class RealmHelper { public static RealmModel saveObj(RealmObject realmObject, Realm realm) { realm.beginTransaction(); RealmObject newRealmObject = realm.copyToRealm(realmObject); realm.commitTransaction(); return newRealmObject; } } 

Usando Realm más nuevo que v0.88.3, ​​no se llama a ningún RealmChangeListener ( rcl ) si algo se inserta en NLService .

Traté de adjuntar rcl directamente a Realm , RealmResults y RealmObject , nada funciona.

La aplicación tiene, por ejemplo, simples rcl para RealmResults.size() y varios RecyclerAdapters y el rcl dentro de RealmRecyclerViewAdapter nunca se llama.

Sin embargo, la ejecución de las consultas funciona y aparece la “información faltante”. Además, si algo se inserta en ui o en cualquier otro hilo, se llama a rcl y aparece “datos faltantes”.

Me quedé durante meses en Realm 0.88.3 porque no puedo llevarlo a trabajar con ninguna versión más nueva de Realm. Con 0.88.3 mRealm.refresh(); se llamó en NLService, esto no está disponible en versiones más nuevas y .waitForChange bloquea infinitamente.

Manifest.xml:

      

Puedo ver dos soluciones para esto, ya sea usar un hilo looper (HandlerThread) con setAutoRefresh(true) (y llamar a setAutoRefresh(false) antes de Looper.quit() ), o forzar una actualización para la instancia de Realm en el hilo.


NOTA: Esto depende de los métodos internos del paquete. Tener cuidado.

En v 1.1.1 (y v1.2.0), – y cualquier versión anterior a 3.0.0 – en lugar de la siguiente línea

 // mRealm.waitForChange(); / mRealm.refresh(); 

Podría forzar la actualización en el hilo local a través del HandlerController asociado con la instancia de Realm usando material interno del paquete

 package io.realm; public class RealmRefresh { public static void refreshRealm(Realm realm) { Message message = Message.obtain(); message.what = HandlerControllerConstants.LOCAL_COMMIT; realm.handlerController.handleMessage(message); } } 

Y luego llama

  mRealm = Realm.getDefaultInstance(); RealmHelper.saveObj(myRealmObject, mRealm); RealmRefresh.refreshRealm(mRealm); mRealm.close(); 

Sin embargo, tenga en cuenta los cambios bruscos del registro de cambios, ya que 0.89.0 cambió el comportamiento de la iteración y los resultados ya no se activan durante una transacción activa; pero desde 3.0.0 están de nuevo.


Sin embargo, también debo señalar que si su NotificationListenerService se ejecuta en un proceso remoto, las instancias de Realm no podrán notificarse entre sí.



EDITAR:

En Realm Java 3.0.0, el comportamiento de notificación se modificó por completo y HandlerController ya no existe.

En cambio, lo siguiente debería funcionar:

 package io.realm; public class RealmRefresh { public static void refreshRealm(Realm realm) { realm.sharedRealm.refresh(); } } 

EDITAR:

En Realm 3.2. +, Todo está disponible con

 realm.refresh();