2

I'm using Realm to provide the database for my application. But...

After login, the server returns the data and I create the account (of AccountManager) and save these datas at the database of the application, like this (at an AsyncTask, of course):

UserRealm userRealm = new UserRealm();
//setter of the userRealm...

Realm realm = Realm.getInstance(context);
realm.beginTransaction();
realm.copyToRealmOrUpdate(userRealm);
realm.commitTransaction();
realm.close();

After, I close the LoginActivity and at the onResume of the MainActivity, I try to load the user, like this(at an AsyncTask, again...):

public static UserRealm getUser(Context context) {
  try {
    return Realm.getInstance(context).where(UserRealm.class).findFirst();
  } catch (Exception e) {
    if(DebugUtil.DEBUG) { //enabled
      e.printStackTrace();
    }
  }
  return null;
}

But this returns null, I don't know what happens with it.

UserRealm: https://gist.github.com/ppamorim/88f2553a6ff990876bc6

Pedro Paulo Amorim
  • 1,838
  • 2
  • 27
  • 50

1 Answers1

1

AsyncTask is in a threadpool, and considering you open Realm instances that you never close with your getUser() call, your Realm version becomes locked at the version when you first called getUser().

return Realm.getInstance(context).where(UserRealm.class).findFirst(); // never closed

So even though you commit a transaction on another thread in the threadpool, not all threads will be up to date (because you locked them on an old version by opening Realm instances that are never closed), and sometimes the object will be null.

Solution, close all Realm instances on background threads (or force an update if that's not enough for some reason).

Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428