Android如何在线程上使用Realm

时间:2016-08-04 13:03:41

标签: java android realm

在我的应用程序中,我读了保存在手机上的联系人,这可能需要很长时间,然后我把它放在Thread嵌套我正在使用Realm但是我收到此错误:< / p>

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

我的解决方案无法解决此问题,例如:

new Handler().post(new Runnable() {
    @Override
    public void run() {
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
            }
        });
    }
});

OR

new Handler(getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
            }
        });            
    }
});

在嵌套线程上,

4 个答案:

答案 0 :(得分:4)

您需要在给定线程上使用Realm实例的实例。

new Handler().post(new Runnable() {
    @Override
    public void run() {
        Realm realm = null;
        try {
            realm = Realm.getDefaultInstance();
            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                }
            });
        } finally {
            if(realm != null) {
                realm.close();
            }
        }
    }
});

虽然您不应该在UI线程上进行同步写入。如果您在UI线程上书写,请使用异步事务。

new Handler().post(new Runnable() {
    @Override
    public void run() {
          final Realm realm = Realm.getDefaultInstance();
          realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                }
            }, 
            new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    realm.close();
                }
            }, 
            new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable e) {
                    realm.close();
                }
            });
    }
});

答案 1 :(得分:3)

问题不是你在另一个线程中使用Realm,问题是你在另一个线程中使用了真实的instance。通常这是一个简单的修复,类似的应该做:

Realm realmForThisThread = Realm.getDefaultInstance();
realmForThisThread.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
    }
}
...
realmForThisThread.close();

答案 2 :(得分:0)

您现在可以使用Realm自己的异步块来完成工作。

realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                // Some working is here.
            }
        }, new Realm.Transaction.OnSuccess() {
            // Some proceesing lines are here.
        }, new Realm.Transaction.OnError() {
            Log.d("AsyncTransaction", "ERROR");
        });

请注意,在execute(Realm realm)方法中,您需要对所有事务使用此领域对象,而不是全局领域对象。

答案 3 :(得分:-1)

在任何线程中使用try with resources。您不需要关闭领域实例。它会自动关闭。

try (Realm mRealm = Realm.getDefaultInstance()) {
        mRealm.executeTransaction(realm -> realm.insertOrUpdate(mData));
    }