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();
Другие вопросы по тегам