First, previous answers to similar questions on SO didn't helped me at all.
Sometimes when calling executeTransactionAsync()
I don't get refreshed data on UI thread in onSuccess
method.
For example, in the following snippet I have a part of the callback instance that should store received data to Realm. This callback instance is created in the UI thread (of course):
@Override
public void onResponse(final Response<TicketAddItemResult> response, Retrofit retrofit) {
if (!isSuccess()) {
return;
}
Realm realm = Realm.getDefaultInstance();
if (realm.isClosed()) return;
try {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
RealmTicketsHandler.updateCurrentTicket(realm, response.body().result);
//!!!! Underneath log sometimes from here shows different result than the log in onSuccess with the same query
Log.d(TAG, "execute: (thread) size = " + RealmTicketsHandler.getCurrentTicket(realm).getTicketItems().size() );
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
Realm realm = Realm.getDefaultInstance();
try {
Log.d(TAG, "execute: (onSuccess) size = " + RealmTicketsHandler.getCurrentTicket(realm).getTicketItems().size() );
} finally {
realm.close();
}
postEvent(new TicketRefreshed());
}
});
} finally {
realm.close();
}
}
In the method RealmTicketsHandler.updateCurrentTicket(realm, data)
I just get object (Ticket
) from realm, create new object (TicketItem
) which will be added to RealmList<TicketItem>
and that's it.
Nevertheless, after updating Realm in background thread, log from execute()
method of Realm.Transaction
object shows me that everything is added correctly, but in the OnSuccess()
method of Realm.Transaction.OnSuccess
instance, log sometimes doesn't show expected result.
Object of TicketItem
doesn't have any references to Ticket
.
Could someone explain me why is this happening?
Realm version: 4.2.0, but the same behaviour can be experienced in 4.1.1
NOTE: opening Realm in onSuccess
is done just to directly show if the data is refreshed in the current thread.
NOTE 2: I also have some background threads without loopers that use realm, but they act as they should and data is quickly refreshed on the UI thread.
This should be an expected behavior, onSuccess()
will guarantee two things:
onSuccess()
is called.The below case may help you to understand why you see different logs in the transaction block and onSuccess()
.
executeTransactionAsync()
to change the data to version 1
.1
.2
.2
and 3
. onSuccess()
is called, and you are not only seeing the changes in step 2, but also together with data changes in step 3. So you may see the data version 3 in the onSuccess()
callback.Be noticed that, onSuccess()
only guarantees that you will have the data changed in the async transaction, but it won't and cannot (well, due to concurrency is hard to guarantee this) guarantee you only see the data changes in the corresponding async transaction. The data changed later could also be seen in the onSuccess()
.