Reputation: 6150
I have a fairly simple managed Realm object RealmAlertItem
consisting of a few Strings and floats. I have a function showAlertNotification()
which gets called subsequently (triggered from outside from the network) and it relies on the fact that previous execution is fully done before the next call. In this function I just change one float field (see setHigh()
and setLow()
below). If both are 0, I delete the object.
However, it seems Realm can't update the object in time and on 2nd call of the function, the object still has old high
and low
values.
Here is logcat:
08:47:04.180 D/debug: showAlertNotification(), guid: 58dfe381-b615-4ce0-beaf-5abb9b0733ac
08:47:04.185 D/debug: high 10000.0 , low 10800.0
08:47:04.205 D/debug: b // here we call RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.setHigh(0));
08:47:04.214 /debug: showAlertNotification(), guid: 58dfe381-b615-4ce0-beaf-5abb9b0733ac
08:47:04.215 /debug: high 10000.0 , low 10800.0 // here high should be 0!
08:47:04.224 /debug: d
As you can see the second invocation happens very fast after the 1st one (about 30ms later).
Here is code:
private void showAlertNotification(RemoteMessage remoteMessage, String coinSlug, String coinName, Bitmap logo) {
Log.d("debug", "showAlertNotification(), guid: " + remoteMessage.getData().get("guid"));
RealmAlertItem alert = RealmInstance.getThreadRealm().where(RealmAlertItem.class).equalTo("guid", remoteMessage.getData().get("guid")).findFirst();
if(alert == null)
return;
... some work
// disable/delete this alert
if(!alert.isRepeating()) {
if (isHighLimit) {
if (alert.getLow() == 0) {
Log.d("debug", "a");
RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.deleteFromRealm());
} else {
Log.d("debug", "b");
RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.setHigh(0));
}
} else {
if (alert.getHigh() == 0) {
Log.d("debug", "c");
RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.deleteFromRealm());
} else {
Log.d("debug", "d");
RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.setLow(0));
}
}
}
Intent intent = new Intent("notifyAlertsChanged");
LocalBroadcastManager.getInstance(MainApplication.getAppContext()).sendBroadcast(intent);
}
If needed, here is my RealmInstance Singleton:
public class RealmInstance {
private Realm realm;
private static RealmInstance realmInstance;
public static RealmInstance getInstance() {
if (realmInstance == null) {
realmInstance = new RealmInstance();
}
return realmInstance;
}
private RealmInstance() {
try {
realm = Realm.getDefaultInstance();
} catch (IllegalStateException err) {
init(MainApplication.getAppContext());
realm = Realm.getDefaultInstance();
}
}
public Realm getRealm() {
return realm;
}
public static Realm getThreadRealm() {
return Realm.getDefaultInstance();
}
public static void init(Context context) {
Realm.init(context);
RealmConfiguration config = new RealmConfiguration
.Builder()
.schemaVersion(13)
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(config);
}
}
How do I solve this?
Upvotes: 1
Views: 108
Reputation: 2096
You need to init your Realm configuration in your Application.java
, and call Realm.getDefaultInstance()
when you need it (i.e get rid of your singleton class).
You also need to close realm instances after you used it, or you get side effects like you are experimenting and later you'll have performance issues.
Upvotes: 1