Android: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created

MrRobot9 picture MrRobot9 · May 28, 2018 · Viewed 7.2k times · Source

So inside a IntentService, the app maybe active or inactive , onHandleIntent gets called , where I have placed this below code.This is where I store the data into realm.

 Realm realm = null;
    try { 
        realm = Realm.getDefaultInstance();
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {

                for (AppItem item : items) {
                    AppItem item2 = realm.createObject(AppItem.class, UUID.randomUUID().toString());
                    item2.mName = item.mName;
                    item2.mCount = item.mCount;
                    item2.mUsageTime = item.mUsageTime;
                }
            }
        });
    } finally {
        if (realm != null) {
            realm.close();
        }
    }

Then I am trying to access it in onPostExecute in AsyncTask, In doInBackground, I am getting the RealmResults<AppItem>, then storing it into List <AppItem> and sending it to onPostExecute where this code is placed. appItems is ReamObject here

 Realm backgroundRealm = Realm.getDefaultInstance();
            backgroundRealm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    for (AppItem item : appItems) { 
 //getting error here   if (item.mUsageTime <= 0) continue;
                        mTotal += item.mUsageTime;
                        item.mCanOpen = mPackageManager.getLaunchIntentForPackage(item.mPackageName) != null;


               }
              }
            });

Both I have done using executeTransactionAsync, still I get the following error.

java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

Answer

Moonbloom picture Moonbloom · May 29, 2018

As per the error message: Once you obtain any Realm objects on 1 thread, they can ONLY be accessed on that thread. Any access on other threads will throw that exception.

"doInBackground" from AsyncTask is run on a background thread. "onPostExecute" is run on the UI thread. So here you get Realm objects on a background thread, and try to access them on the UI thread => Exception.

You should either do everything on the background thread, or everything on the UI thread.

If you're doing a very complex query, i suggest using "findAllAsync" on the RealmQuery, as this will run the query on a background thread, and move them over to the main thread, but it's handled internally by Realm in a safe manner.