Android Realm - 从服务访问 Realm 对象



我有一个在我的活动中创建的领域对象。我需要能够在我创建的服务中访问此对象。但是,我在服务中创建 Realm 对象时收到错误

        mRealm = Realm.getInstance(getApplicationContext());

java.lang.IllegalStateException:来自不正确线程的领域访问。 Realm 对象只能在创建它们的线程上访问

现在我明白这意味着,由于 realm 对象是在我的活动上创建的,所以我无法从后台线程访问它。但是,除了创建自己的自定义处理程序线程之外,我没有找到一种简单的方法来解决这个问题,但这似乎是一种笨拙的方法。

我在这里错过了什么,还是真的没有更好的方法可以从不同的线程中访问 Realm 对象?

更新:

我深入研究了

一点,以找出在IntentService中,onHandleIntent方法在与类中的其他方法不同的线程中运行。因此,我无法创建一个类级 Realm 实例,并且无法与 onHandleIntent 方法内部和外部的实例进行交互。这就是导致线程异常的原因。除了在每个方法中创建一个单独的 Realm 实例之外,我需要访问该对象并一遍又一遍地检索它,我认为 Ilya Tretyakov 的答案将是最好的。我可以从构造函数中的 realm 复制对象,然后在服务的整个生命周期中使用它。任何需要写回 Realm 对象的方法都需要在该方法中实例化自己的 Realm 实例。

您可以尝试使用 realm.copyFromRealm(youRealmObject); .这些方法将 Realm 数据复制到普通的 Java 对象中,并将它们与 Realm 分离。

下面是用法示例:

youRealmObject = realm.copyFromRealm(youRealmObject);

以下是文档中有关它的信息:

为已经持久化的 RealmObject 创建一个独立的内存中副本。 这是一个深层副本,将复制所有引用的对象。复制的 对象都已从 Realm 中分离出来,因此它们将不再 自动更新。这意味着复制的对象可能会 包含不再与其他托管 Realm 数据库一致的数据 对象。警告:对复制对象所做的任何更改都可以合并回来 使用 copyToRealmOrUpdate(RealmObject) 进入 Realm,但所有字段都将 被覆盖,而不仅仅是那些被更改的。这包括 对其他对象的引用,并可能覆盖所做的更改 通过其他线程。

https://realm.io/docs/java/latest/api/io/realm/Realm.html#copyFromRealm-E-

从技术上讲,您应该在后台线程的开头打开 Realm 实例,在该后台执行结束时关闭它,然后将其传递给介于两者之间的方法。

public void handleIntent() { // or doInBackground etc
    Realm realm = null;
    try {
         realm = Realm.getDefaultInstance();
         .... 
         MyObj obj = realm.where(MyObj.class)
                          .equalTo(MyObjFields.ID, myObjId)
                          .findFirst(); // get by id
         .... 
    } finally {
         if(realm != null) {
              realm.close(); // important 
         } 
    } 
} 

使用realm.copyFromRealm()是一种解决方法,而不是解决方案。


在 AS 3.0 中,无论您的 minSDK 是什么,您实际上都可以使用 try-with-resources(就像您使用 Retrolambda 一样):

public void handleIntent() { // or doInBackground etc
    try(Realm realm = Realm.getDefaultInstance()) {
         .... 
         MyObj obj = realm.where(MyObj.class)
                          .equalTo(MyObjFields.ID, myObjId)
                          .findFirst(); // get by id
         .... 
    } // auto-close
} 

最新更新