型号:
public class Dog extends RealmObject {
@PrimaryKey
public String id = UUID.randomUUID().toString();
... other random String attributes
public Dog mother;
}
的活动:
public class CustomActivity extends AppCompatActivity {
private Realm realm;
private Dog dog = new Dog();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
realm = Realm.getDefaultInstance();
}
@Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
private void setMother(int id) {
dog.mother = realm.where(Dog.class).equalTo(ID, id).findFirst();
}
private void saveDog() {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(dog);
}
});
}
}
当我运行此代码时,它给了我这个错误:
Objects which belong to Realm instances in other threads cannot be copied into this Realm instance.
我使用它的唯一方法是使用realm.copyFromRealm(),但整个对象被复制,我不想要它。
我应该单独保存母亲身份并在我的应用程序中随时随地查询母亲吗?
有没有办法实现我在不复制整个对象的情况下尝试做的事情?
编辑:
我原本以为整个对象是使用realm.copyFromRealm()复制的,因为它在领域浏览器中看起来很像。
我刚刚测试了更新dog.mother中的字段,它更新了链接对象,这意味着它不是副本
我仍然不知道这是实现我想做的最好的方式还是正确的方法,但它能做到我想要的。
答案 0 :(得分:1)
您的异常发生是因为您在UI线程上构造了Dog
对象,然后将其传递给异步工作线程,但这意味着您还将引用传递给mother
,而不是#39} ; t允许。相反,您需要在async方法中进行设置,如下所示:
private void saveDog() {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
// This will give you mother reference on the correct thread
setMother(motherId, dog);
realm.copyToRealmOrUpdate(dog);
}
});
}
答案 1 :(得分:1)
private Realm realm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
realm = Realm.getDefaultInstance(); //<--- this is on ui thread
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(dog); // <-- this is on background thread
//...
private void setMother(int id) {
dog.mother = realm.where(Dog.class).equalTo(ID, id).findFirst(); // <-- uses UI-thread Realm stored as field
因此,如果您在后台线程上使用setMother()
,您将访问UI线程Realm,并且它会抛出IllegalStateException。
您需要将给定线程的Realm传递给方法。
private void setMother(Realm realm, Dog dog, int id) {
dog.mother = realm.where(Dog.class).equalTo(ID, id).findFirst();
}
private void saveDog() {
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Dog _dog = realm.copyToRealmOrUpdate(dog);
setMother(realm, _dog, id);
}
});