问题
I\'m doing Realm insertions on a extended NotificationListenerService, like this:
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;
}
}
Using Realm newer than v0.88.3, not a single RealmChangeListener (rcl) gets called if anything gets inserted in NLService.
I tried attaching rcl\'s directly to Realm, RealmResults and RealmObject, nothing works.
The App has for example simple rcl\'s for RealmResults<myRealmObject>.size() and
several RecyclerAdapters and the rcl inside RealmRecyclerViewAdapter is never called.
Rerunning queries however works and the \"missing data\" shows up. Also if anything gets inserted on ui- or any other thread, rcl\'s get called and \"missing data\" shows up.
I stayed for months on Realm 0.88.3 because I can not bring it to work with any newer Realm version. With 0.88.3 mRealm.refresh(); was called in NLService, this is not available in newer versions and .waitForChange blocks endlessly.
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:
I can see two solutions to this, either use a looper thread (HandlerThread) with setAutoRefresh(true) (and call setAutoRefresh(false) before Looper.quit()), or force a refresh for the Realm instance on the thread.
NOTE: This relies on package-internal methods. Beware.
In v 1.1.1 (and v1.2.0), - and any version before 3.0.0 - instead of the following line
// mRealm.waitForChange(); / mRealm.refresh();
You could force the update on the local thread through the HandlerController associated with the Realm instance using package-internal stuff
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);
}
}
And then call
mRealm = Realm.getDefaultInstance();
RealmHelper.saveObj(myRealmObject, mRealm);
RealmRefresh.refreshRealm(mRealm);
mRealm.close();
Please note the change log's breaking changes though, because 0.89.0 changed iteration behavior, and results are no longer live during an active transaction; but from 3.0.0 they are again.
However, I must also note that if your NotificationListenerService is running in a remote process, then the Realm instances won't be able to notify each other.
EDIT:
In Realm Java 3.0.0, the notification behavior was changed completely, and HandlerController no longer exists.
Instead, the following should work:
package io.realm;
public class RealmRefresh {
public static void refreshRealm(Realm realm) {
realm.sharedRealm.refresh();
}
}
EDIT:
In Realm 3.2.+, this is all available with
realm.refresh();
来源:https://stackoverflow.com/questions/38833163/realmchangelistener-does-not-get-called-when-realm-gets-updated-in-notificationl