Android领域 – 从服务访问领域对象

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

mRealm = Realm.getInstance(getApplicationContext()); 

java.lang.IllegalStateException:从错误的线程访问Realm。 Realm对象只能在创建它们的线程上访问

现在我理解这意味着因为领域对象是在我的活动上创建的,所以我无法从后台线程访问它。 但是,除了创建我自己的自定义处理程序线程之外,我找不到一个简单的方法,但这似乎是一种笨重的方式。

我在这里遗漏了什么,或者是否真的没有更好的方法可以从不同的线程中访问Realm对象?

更新:

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

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

以下是使用示例:

 youRealmObject = realm.copyFromRealm(youRealmObject); 

以下是来自docs的相关信息:

制作已经持久化的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 }