可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm setting a property on a realm object with another realm object which is a different class, however I'm getting the error: 'value' is not avalid managed object.
realmObject.setAnotherRealmObject(classInstance.returnAnotherRealmObjectWithValues())
The class instance receives anotherRealmObject constructor and returns it through the method with values from widgets:
public ClassInstance(AnotherRealmObject anotherRealmObject){ mAnotherRealmObject = anotherRealmObject; } public AnotherRealmObject returnAnotherRealmObjectWithValues(){ mAnotherRealmObject.setId(RandomUtil.randomNumbersAndLetters(5)); mAnotherRealmObject.setName(etName.getText().toString()); return mAnotherRealmObject; }
I'm creating the new Another Realm Object the right way (I think):
mAnotherRealmObject = mRealmInstance.createObject(AnotherRealmObject.class);
Is it because I'm returning anotherRealmObject wherein it is already modified because of the passing reference?
回答1:
Upon researching there is a method on realm objects to check if it is valid:
realmObject.isValid();
There are two ways I know how to instantiate a realmObject:
RealmObject realmObj = new RealObject(); //Invalid RealmObject realmObj = realmInstance().createObject(RealmClass.class); //Valid
I was using parceler to pass realmObjects around. Passing a realmObject through parceler and unwrapping it and assigning it to a realmObject variable would make it invalid:
RealmObject realmObj = Parcels.unwrap(data.getParcelableExtra("realmObject"));
Solution 1 - Pass the unique identifer, then query the realm object:
int uniqueId = Parcels.unwrap(data.getParcelableExtra("uniqueId"));
Solution 2 - Pass the values, retrieve it, create a realmObject through a realmInstance and assign the values.
//Retrieve values String value1 = Parcels.unwrap(data.getParcelableExtra("value1")); String value2 = Parcels.unwrap(data.getParcelableExtra("value2")); //Create realmObject 'properly' RealmObject realmObj = realmInstance().createObject(RealmClass.class); //Assign retrieved values realmObj.setValue1(value1); realmObj.setValue2(value2);
This way you won't get an invalid realm object.
回答2:
All managed RealmObjects and RealmResults belong to a specific Realm instance. After the corresponding Realm instance gets closed, the RealmObject becomes invalid.
Like below case:
Realm realm = Realm.getInstance(context); realm.beginTransaction(); MyObject obj = realm.createObject(MyObject.class); realm.commitTransaction(); realm.close(); realm = Realm.getInstance(context); realm.beginTransaction(); MyObject obj2 = realm.where(MyObject2.class).findFirst(); obj2.setObj1(obj); // Throws exception, because of the obj's Realm instance is closed. It is invalid now. realm.commitTransaction();
You may get some ideas about control the Realm's instance life cycle through this doc