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

荒凉一梦 提交于 2019-12-20 05:52:05

问题


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.

回答1:


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.




回答2:


for (AppItem item : appItems) { 

If appItems contains managed RealmObjects that you obtained from a RealmResults on the UI thread, then accessing them will fail on the background thread.

realm.executeTransactionAsync((realm) -> { gives you a Realm as parameter that is running on Realm's thread executor, so that must be used to obtain managed RealmResults/RealmObjects inside the transaction.

So you need to re-query the objects inside realm.executeTransactionAsync if the objects are managed.

            public void execute(Realm realm) {
                for (AppItem item : realm.where(AppItem.class).findAll()) { 


来源:https://stackoverflow.com/questions/50573802/android-realm-access-from-incorrect-thread-realm-objects-can-only-be-accessed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!