RealmChangeListener не вызывается, когда Realm обновляется в NotificationListenerService
Я делаю вставки Realm в расширенный сервис NotificationListenerService, например:
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;
}
}
Использование Realm новее, чем v0.88.3, ни одного RealmChangeListener
(rcl) вызывается, если что-то вставлено в NLService
,
Я пытался прикрепить rcl прямо к Realm
, RealmResults
а также RealmObject
ничего не работает.
Приложение имеет, например, простые Rcl для RealmResults<myRealmObject>.size()
и несколько RecyclerAdapters и Rcl внутри RealmRecyclerViewAdapter
никогда не называется.
Однако повторные запросы работают, и появляются "пропущенные данные". Также, если что-то вставляется в пользовательский или любой другой поток, вызывается rcl и появляются "отсутствующие данные".
Я несколько месяцев оставался на Realm 0.88.3, потому что не могу заставить его работать с любой новой версией Realm. С 0.88.3 mRealm.refresh();
был вызван в NLService, это не доступно в более новых версиях и .waitForChange
блокирует бесконечно.
manifest.xml:
<service
android:name=".service.NLService"
android:label="@string/nl_service"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService"/>
</intent-filter>
</service>
1 ответ
Я вижу два решения для этого, либо использовать петлитель потока (HandlerThread) с setAutoRefresh(true)
(и позвоните setAutoRefresh(false)
до Looper.quit()
) или принудительно обновите экземпляр Realm в потоке.
ПРИМЕЧАНИЕ. Это зависит от внутренних методов пакета. Осторожно.
В v 1.1.1 (и v1.2.0) - и любой версии до 3.0.0 - вместо следующей строки
// mRealm.waitForChange(); / mRealm.refresh();
Вы можете принудительно обновить локальный поток через HandlerController
связан с экземпляром Realm с использованием внутреннего пакета
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);
}
}
А потом позвони
mRealm = Realm.getDefaultInstance();
RealmHelper.saveObj(myRealmObject, mRealm);
RealmRefresh.refreshRealm(mRealm);
mRealm.close();
Пожалуйста, обратите внимание на критические изменения журнала изменений, потому что 0.89.0 изменил поведение итерации, и результаты больше не отображаются во время активной транзакции; но с 3.0.0 они снова.
Тем не менее, я также должен отметить, что если ваш NotificationListenerService
выполняется в удаленном процессе, тогда экземпляры Realm не смогут уведомлять друг друга.
РЕДАКТИРОВАТЬ:
В Realm Java 3.0.0 поведение уведомлений было полностью изменено, и HandlerController
более не существует.
Вместо этого должно работать следующее:
package io.realm;
public class RealmRefresh {
public static void refreshRealm(Realm realm) {
realm.sharedRealm.refresh();
}
}
РЕДАКТИРОВАТЬ:
В Realm 3.2.+ Все это доступно с
realm.refresh();