Reputation: 2487
I am having trouble with waiting for fresh data on a worker thread. The data object is copied to realm on a main thread, but almost immediately after that I need to access this object from a worker thread, which then reports that no such object exists in realm right now ( its newly opened realm instance ) . I remember that there was a method load()
that would block execution to the point of next update, but it was removed in newer versions. And I can't use change notification for this as this is not a Looper thread..
The only way I can think of right now is to sleep the thread for some magic period of time and pray to god that it has updated already, but that approach is imho wildly indeterministic.
Can anybody advise here, how can I ensure that I read the most current data at the time ?
Upvotes: 0
Views: 1700
Reputation: 185
using realm.beginTransaction() and realm.commitTransaction() instead of realm.executeTransaction(Realm.Transaction)
The problem with this is that executeTransaction() automatically handles calling realm.cancelTransaction() in case an exception is thrown, while the other alternative typically neglects the try-catch.
Yes, you’re supposed to call cancel on transactions that aren’t going to end up being committed.
For example, on background threads:
// SAY NO TO THIS
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction(); // NO
realm.copyToRealm(dog)
realm.commitTransaction(); // NO NO NO NO NO
// YOU NEED TO CLOSE THE REALM
// ----------------------
// SAY YES TO THIS
Realm realm = null;
try { // I could use try-with-resources here
realm = Realm.getDefaultInstance();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insertOrUpdate(dog);
}
});
} finally {
if(realm != null) {
realm.close();
}
}
// OR IN SHORT (Retrolambda)
try(Realm realmInstance = Realm.getDefaultInstance()) {
realmInstance.executeTransaction((realm) -> realm.insertOrUpdate(dog));
}
The problem with this is that on background threads, having an open Realm instance that you don’t close even when the thread execution is over is very costly, and can cause strange errors. As such, it’s recommended to close the Realm on your background thread when the execution is done in a finally block. This includes IntentServices.
Upvotes: 0
Reputation: 81539
A possible hack would be to create a transaction that you cancel at the end.
realm.beginTransaction(); // blocks while there are other transactions
... // you always see the latest version of the Realm here
realm.cancelTransaction();
This works if the thread is started after the UI thread saves the object into the Realm.
You can also try this workaround: https://stackoverflow.com/a/38839808/2413303 (although it doesn't really help with waiting)
Upvotes: 1
Reputation: 3282
try using QueryListener, which is trigger whenewer object, satisfying certain criteria is updated
Upvotes: 0