It seems like my RealmObject values are being hidden by the RealmProxy class, but can be set from the proxyclass.
My model is pretty straight forward as you can see.
public class GroupRealm extends RealmObject {
#PrimaryKey
public String id;
#Index
public String name;
public String imageUrl;
public int order;
public GroupRealm parent;
public RealmList<GroupRealm> children;
public RealmList<ContentRealm> contents;
}
This is how i am setting the values(db is a valid Realm, and everything is in a transaction that commits fine):
GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst();
if(gr==null){
gr = db.createObject(GroupRealm.class,g.GroupID);
}
gr.imageUrl = g.GlyphUrl;
gr.name = g.Title;
gr.order = g.OrderNum;
The image below is what I get when i query the db latter on.(same variable name not same place in code)
In my android.library where my RealmObjects are defined project I have the necessary plugins.
apply plugin: 'com.android.library'
apply plugin: 'realm-android'
and on the project level I am setting the correct dependencies:
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath "io.realm:realm-gradle-plugin:0.90.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
I am out of ideas. If I try to access anything I retrieve the GroupRealm as expected but all of the public properties exposed through the proxy class return null!
Relevant FAQ in documentation: https://realm.io/docs/java/latest/#debugging
Realm uses Android Gradle Transform API. It gives a possibility to manipulate compiled class files before they are converted to dex files.
More details inside io.realm.transformer.RealmTransformer and io.realm.transformer. BytecodeModifier classes which can be found in the realm's github.
What RealmTransformer does, among others, is:
replacing all accesses to fields of user's RealmObjects with the appropriate Realm accessors.
You can also check result classes inside folder app/build/intermediates/transforms/RealmTransformer/
Example of setter:
Line of your code:
gr.imageUrl = g.GlyphUrl;
will be replaced with something like this:
String var5 = g.GlyphUrl;
gr.realmSet$imageUrl(var5);
Example of getter:
String url = gr.imageUrl;
will be replaced with something like this:
String url = gr.realmGet$imageUrl();
Example use case
You have created class GroupRealm. Realm using Transform API generates GroupRealmRealmProxy. This proxy class looks like this:
public class GroupRealmRealmProxy extends GroupRealm implements RealmObjectProxy, GroupRealmRealmProxyInterface {
private final GroupRealmRealmProxy.GroupRealmColumnInfo columnInfo;
private final ProxyState proxyState;
private RealmList<GroupRealm> childrenRealmList;
private RealmList<ContentRealm> contentsRealmList;
private static final List<String> FIELD_NAMES;
GroupRealmRealmProxy(ColumnInfo columnInfo) {
...
}
public String realmGet$id() {
this.proxyState.getRealm$realm().checkIfValid();
return this.proxyState.getRow$realm().getString(this.columnInfo.idIndex);
}
public void realmSet$id(String value) {
this.proxyState.getRealm$realm().checkIfValid();
if(value == null) {
this.proxyState.getRow$realm().setNull(this.columnInfo.idIndex);
} else {
this.proxyState.getRow$realm().setString(this.columnInfo.idIndex, value);
}
}
public String realmGet$name() {
this.proxyState.getRealm$realm().checkIfValid();
return this.proxyState.getRow$realm().getString(this.columnInfo.nameIndex);
}
public void realmSet$name(String value) {
this.proxyState.getRealm$realm().checkIfValid();
if(value == null) {
this.proxyState.getRow$realm().setNull(this.columnInfo.nameIndex);
} else {
this.proxyState.getRow$realm().setString(this.columnInfo.nameIndex, value);
}
}
...
}
You can observe that methods realmSet$name and realmGet$name don't have access to field name declared in the class GroupRealm. They use proxyState.
Now, let's back to the usage of GroupRealm. When you debug your code:
GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst();
if(gr==null){
gr = db.createObject(GroupRealm.class,g.GroupID);
}
gr.imageUrl = g.GlyphUrl;
gr.name = g.Title;
gr.order = g.OrderNum;
in a reality it's decompiled version looks like this:
GroupRealm gr = (GroupRealm)realm.where(GroupRealm.class).equalTo("id", g.GroupId).findFirst();
if(gr == null) {
gr = (GroupRealm)realm.createObject(GroupRealm.class, g.GroupId);
}
String var7 = g.GlyphUrl;
gr.realmSet$imageUrl(var7);
var7 = g.Title;
gr.realmSet$name(var7);
int var8 = g.OrderNum;
gr.realmSet$order(var8);
First of all, gr is the instance of GroupRealmRealmProxy class. As you can see, setting of gr.name is replaced by gr.realmSet$name(var7). It means that the field name of GroupRealm is never used. The situation is analogous in the case of realmGet$.
While debugging you see your version of source code but actually you're using a modified version with injected methods realmSet$ and realmGet$.
The fields are null. You access the properties through a native method that replaces all field access. Previously (before 0.88.0) it used to create a dynamic proxy that overrode your getters and setters to use their native proxy implementation.
The fields don't have values. But as you can see, the Realm object has the values just fine: it says so in the toString() value.
There is nothing to be done about this. Because of the "clever" thing that Realm is doing, the debugger is completely prevented from doing what it is supposed to. You'll have to rely on a lot of Log.d statements.
I'm sorry. That's just the reality of it.
This is because of the Realm proxies model which is zero-copy storage.
You can use Kotlin Realm extension, Vicpinm library https://github.com/vicpinm/Kotlin-Realm-Extensions
If you still want to use in Java then you achieve it by:-
Realm.getDefaultInstance().copyFromRealm(realmObject)
The answers above are all right if you directly use an RealmObject retrieved from your Realm. With Managed RealmObject (Objects "directly" connected with your Realm, so the "Real Instance" of the object inside your Realm which you can Modify only inside RealmTransaction and which changes will affect all other Managed RealmInstance instantly) you can't see their values inside of the debugger because of the proxy.
Anyway you can work around this by using a NO MANAGED object, so by COPYING the RealmObject from the realm:
MyRealmObject obj = getRealmObjectFromRealm();
if(obj != null){
obj = mRealm.copyFromRealm(obj);
}
This way you will see all properties of your realm object inside the debugger.
Obviously if you need to use a Managed Realm Object inside your code, when you are debugging you need to change your code by creating another "MyRealmObject" instance which is a copy from the Realm of the other "MyRealmObject".
This way you will see all objects properties inside the debugger (:
Hope this is helpful,
Greetings & have a nice coding!
:D
Related
It seems like my RealmObject values are being hidden by the RealmProxy class, but can be set from the proxyclass.
My model is pretty straight forward as you can see.
public class GroupRealm extends RealmObject {
#PrimaryKey
public String id;
#Index
public String name;
public String imageUrl;
public int order;
public GroupRealm parent;
public RealmList<GroupRealm> children;
public RealmList<ContentRealm> contents;
}
This is how i am setting the values(db is a valid Realm, and everything is in a transaction that commits fine):
GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst();
if(gr==null){
gr = db.createObject(GroupRealm.class,g.GroupID);
}
gr.imageUrl = g.GlyphUrl;
gr.name = g.Title;
gr.order = g.OrderNum;
The image below is what I get when i query the db latter on.(same variable name not same place in code)
In my android.library where my RealmObjects are defined project I have the necessary plugins.
apply plugin: 'com.android.library'
apply plugin: 'realm-android'
and on the project level I am setting the correct dependencies:
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath "io.realm:realm-gradle-plugin:0.90.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
I am out of ideas. If I try to access anything I retrieve the GroupRealm as expected but all of the public properties exposed through the proxy class return null!
Relevant FAQ in documentation: https://realm.io/docs/java/latest/#debugging
Realm uses Android Gradle Transform API. It gives a possibility to manipulate compiled class files before they are converted to dex files.
More details inside io.realm.transformer.RealmTransformer and io.realm.transformer. BytecodeModifier classes which can be found in the realm's github.
What RealmTransformer does, among others, is:
replacing all accesses to fields of user's RealmObjects with the appropriate Realm accessors.
You can also check result classes inside folder app/build/intermediates/transforms/RealmTransformer/
Example of setter:
Line of your code:
gr.imageUrl = g.GlyphUrl;
will be replaced with something like this:
String var5 = g.GlyphUrl;
gr.realmSet$imageUrl(var5);
Example of getter:
String url = gr.imageUrl;
will be replaced with something like this:
String url = gr.realmGet$imageUrl();
Example use case
You have created class GroupRealm. Realm using Transform API generates GroupRealmRealmProxy. This proxy class looks like this:
public class GroupRealmRealmProxy extends GroupRealm implements RealmObjectProxy, GroupRealmRealmProxyInterface {
private final GroupRealmRealmProxy.GroupRealmColumnInfo columnInfo;
private final ProxyState proxyState;
private RealmList<GroupRealm> childrenRealmList;
private RealmList<ContentRealm> contentsRealmList;
private static final List<String> FIELD_NAMES;
GroupRealmRealmProxy(ColumnInfo columnInfo) {
...
}
public String realmGet$id() {
this.proxyState.getRealm$realm().checkIfValid();
return this.proxyState.getRow$realm().getString(this.columnInfo.idIndex);
}
public void realmSet$id(String value) {
this.proxyState.getRealm$realm().checkIfValid();
if(value == null) {
this.proxyState.getRow$realm().setNull(this.columnInfo.idIndex);
} else {
this.proxyState.getRow$realm().setString(this.columnInfo.idIndex, value);
}
}
public String realmGet$name() {
this.proxyState.getRealm$realm().checkIfValid();
return this.proxyState.getRow$realm().getString(this.columnInfo.nameIndex);
}
public void realmSet$name(String value) {
this.proxyState.getRealm$realm().checkIfValid();
if(value == null) {
this.proxyState.getRow$realm().setNull(this.columnInfo.nameIndex);
} else {
this.proxyState.getRow$realm().setString(this.columnInfo.nameIndex, value);
}
}
...
}
You can observe that methods realmSet$name and realmGet$name don't have access to field name declared in the class GroupRealm. They use proxyState.
Now, let's back to the usage of GroupRealm. When you debug your code:
GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst();
if(gr==null){
gr = db.createObject(GroupRealm.class,g.GroupID);
}
gr.imageUrl = g.GlyphUrl;
gr.name = g.Title;
gr.order = g.OrderNum;
in a reality it's decompiled version looks like this:
GroupRealm gr = (GroupRealm)realm.where(GroupRealm.class).equalTo("id", g.GroupId).findFirst();
if(gr == null) {
gr = (GroupRealm)realm.createObject(GroupRealm.class, g.GroupId);
}
String var7 = g.GlyphUrl;
gr.realmSet$imageUrl(var7);
var7 = g.Title;
gr.realmSet$name(var7);
int var8 = g.OrderNum;
gr.realmSet$order(var8);
First of all, gr is the instance of GroupRealmRealmProxy class. As you can see, setting of gr.name is replaced by gr.realmSet$name(var7). It means that the field name of GroupRealm is never used. The situation is analogous in the case of realmGet$.
While debugging you see your version of source code but actually you're using a modified version with injected methods realmSet$ and realmGet$.
The fields are null. You access the properties through a native method that replaces all field access. Previously (before 0.88.0) it used to create a dynamic proxy that overrode your getters and setters to use their native proxy implementation.
The fields don't have values. But as you can see, the Realm object has the values just fine: it says so in the toString() value.
There is nothing to be done about this. Because of the "clever" thing that Realm is doing, the debugger is completely prevented from doing what it is supposed to. You'll have to rely on a lot of Log.d statements.
I'm sorry. That's just the reality of it.
This is because of the Realm proxies model which is zero-copy storage.
You can use Kotlin Realm extension, Vicpinm library https://github.com/vicpinm/Kotlin-Realm-Extensions
If you still want to use in Java then you achieve it by:-
Realm.getDefaultInstance().copyFromRealm(realmObject)
The answers above are all right if you directly use an RealmObject retrieved from your Realm. With Managed RealmObject (Objects "directly" connected with your Realm, so the "Real Instance" of the object inside your Realm which you can Modify only inside RealmTransaction and which changes will affect all other Managed RealmInstance instantly) you can't see their values inside of the debugger because of the proxy.
Anyway you can work around this by using a NO MANAGED object, so by COPYING the RealmObject from the realm:
MyRealmObject obj = getRealmObjectFromRealm();
if(obj != null){
obj = mRealm.copyFromRealm(obj);
}
This way you will see all properties of your realm object inside the debugger.
Obviously if you need to use a Managed Realm Object inside your code, when you are debugging you need to change your code by creating another "MyRealmObject" instance which is a copy from the Realm of the other "MyRealmObject".
This way you will see all objects properties inside the debugger (:
Hope this is helpful,
Greetings & have a nice coding!
:D
It seems like my RealmObject values are being hidden by the RealmProxy class, but can be set from the proxyclass.
My model is pretty straight forward as you can see.
public class GroupRealm extends RealmObject {
#PrimaryKey
public String id;
#Index
public String name;
public String imageUrl;
public int order;
public GroupRealm parent;
public RealmList<GroupRealm> children;
public RealmList<ContentRealm> contents;
}
This is how i am setting the values(db is a valid Realm, and everything is in a transaction that commits fine):
GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst();
if(gr==null){
gr = db.createObject(GroupRealm.class,g.GroupID);
}
gr.imageUrl = g.GlyphUrl;
gr.name = g.Title;
gr.order = g.OrderNum;
The image below is what I get when i query the db latter on.(same variable name not same place in code)
In my android.library where my RealmObjects are defined project I have the necessary plugins.
apply plugin: 'com.android.library'
apply plugin: 'realm-android'
and on the project level I am setting the correct dependencies:
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath "io.realm:realm-gradle-plugin:0.90.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
I am out of ideas. If I try to access anything I retrieve the GroupRealm as expected but all of the public properties exposed through the proxy class return null!
Relevant FAQ in documentation: https://realm.io/docs/java/latest/#debugging
Realm uses Android Gradle Transform API. It gives a possibility to manipulate compiled class files before they are converted to dex files.
More details inside io.realm.transformer.RealmTransformer and io.realm.transformer. BytecodeModifier classes which can be found in the realm's github.
What RealmTransformer does, among others, is:
replacing all accesses to fields of user's RealmObjects with the appropriate Realm accessors.
You can also check result classes inside folder app/build/intermediates/transforms/RealmTransformer/
Example of setter:
Line of your code:
gr.imageUrl = g.GlyphUrl;
will be replaced with something like this:
String var5 = g.GlyphUrl;
gr.realmSet$imageUrl(var5);
Example of getter:
String url = gr.imageUrl;
will be replaced with something like this:
String url = gr.realmGet$imageUrl();
Example use case
You have created class GroupRealm. Realm using Transform API generates GroupRealmRealmProxy. This proxy class looks like this:
public class GroupRealmRealmProxy extends GroupRealm implements RealmObjectProxy, GroupRealmRealmProxyInterface {
private final GroupRealmRealmProxy.GroupRealmColumnInfo columnInfo;
private final ProxyState proxyState;
private RealmList<GroupRealm> childrenRealmList;
private RealmList<ContentRealm> contentsRealmList;
private static final List<String> FIELD_NAMES;
GroupRealmRealmProxy(ColumnInfo columnInfo) {
...
}
public String realmGet$id() {
this.proxyState.getRealm$realm().checkIfValid();
return this.proxyState.getRow$realm().getString(this.columnInfo.idIndex);
}
public void realmSet$id(String value) {
this.proxyState.getRealm$realm().checkIfValid();
if(value == null) {
this.proxyState.getRow$realm().setNull(this.columnInfo.idIndex);
} else {
this.proxyState.getRow$realm().setString(this.columnInfo.idIndex, value);
}
}
public String realmGet$name() {
this.proxyState.getRealm$realm().checkIfValid();
return this.proxyState.getRow$realm().getString(this.columnInfo.nameIndex);
}
public void realmSet$name(String value) {
this.proxyState.getRealm$realm().checkIfValid();
if(value == null) {
this.proxyState.getRow$realm().setNull(this.columnInfo.nameIndex);
} else {
this.proxyState.getRow$realm().setString(this.columnInfo.nameIndex, value);
}
}
...
}
You can observe that methods realmSet$name and realmGet$name don't have access to field name declared in the class GroupRealm. They use proxyState.
Now, let's back to the usage of GroupRealm. When you debug your code:
GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst();
if(gr==null){
gr = db.createObject(GroupRealm.class,g.GroupID);
}
gr.imageUrl = g.GlyphUrl;
gr.name = g.Title;
gr.order = g.OrderNum;
in a reality it's decompiled version looks like this:
GroupRealm gr = (GroupRealm)realm.where(GroupRealm.class).equalTo("id", g.GroupId).findFirst();
if(gr == null) {
gr = (GroupRealm)realm.createObject(GroupRealm.class, g.GroupId);
}
String var7 = g.GlyphUrl;
gr.realmSet$imageUrl(var7);
var7 = g.Title;
gr.realmSet$name(var7);
int var8 = g.OrderNum;
gr.realmSet$order(var8);
First of all, gr is the instance of GroupRealmRealmProxy class. As you can see, setting of gr.name is replaced by gr.realmSet$name(var7). It means that the field name of GroupRealm is never used. The situation is analogous in the case of realmGet$.
While debugging you see your version of source code but actually you're using a modified version with injected methods realmSet$ and realmGet$.
The fields are null. You access the properties through a native method that replaces all field access. Previously (before 0.88.0) it used to create a dynamic proxy that overrode your getters and setters to use their native proxy implementation.
The fields don't have values. But as you can see, the Realm object has the values just fine: it says so in the toString() value.
There is nothing to be done about this. Because of the "clever" thing that Realm is doing, the debugger is completely prevented from doing what it is supposed to. You'll have to rely on a lot of Log.d statements.
I'm sorry. That's just the reality of it.
This is because of the Realm proxies model which is zero-copy storage.
You can use Kotlin Realm extension, Vicpinm library https://github.com/vicpinm/Kotlin-Realm-Extensions
If you still want to use in Java then you achieve it by:-
Realm.getDefaultInstance().copyFromRealm(realmObject)
The answers above are all right if you directly use an RealmObject retrieved from your Realm. With Managed RealmObject (Objects "directly" connected with your Realm, so the "Real Instance" of the object inside your Realm which you can Modify only inside RealmTransaction and which changes will affect all other Managed RealmInstance instantly) you can't see their values inside of the debugger because of the proxy.
Anyway you can work around this by using a NO MANAGED object, so by COPYING the RealmObject from the realm:
MyRealmObject obj = getRealmObjectFromRealm();
if(obj != null){
obj = mRealm.copyFromRealm(obj);
}
This way you will see all properties of your realm object inside the debugger.
Obviously if you need to use a Managed Realm Object inside your code, when you are debugging you need to change your code by creating another "MyRealmObject" instance which is a copy from the Realm of the other "MyRealmObject".
This way you will see all objects properties inside the debugger (:
Hope this is helpful,
Greetings & have a nice coding!
:D
Hi I hope someone here can help me, I am working in an android app, I already serialize the following gson object
Screenshot:
the jsonobject has many subclasses like:
PreferencialaboraEstudio,Preferencialaboralarea, and more classes,
I transfer this gson object from an activity to a new activity, in order to deserialize this object I have implemented the following code in the new activity:
Intent intent = getIntent();
String Postulado = intent.getStringExtra("Postulado");//Postulado from extra is actually a gson object
Candidato candidato = gson.fromJson(Postulado, Candidato.class);
CandidatoPreferenciaLaboralEstado preflaboraledo = gson.fromJson(Postulado, CandidatoPreferenciaLaboralEstado.class);
I have the problem in CandidatoPreferenciaLaboralEstado, as you can see in the picture there are two items of this type class in the gson object, but my code only returns the first item and not the second one, is there a way to get all the items of this type "CandidatoPreferenciaLaboralEstado" from the gson?
Thank you very much for your time and assistance in this matter.
Not sure how your root model is, but you can have something like this:
public class Postulado {
private CandidatoPreferenciaLaboralEstado candidatoPreferenciaLaboralEstado;
private CandidatoSoftware candidatoSoftware;
public class CandidatoPreferenciaLaboralEstado {
private List<CandidatoPrefAttributes> candidatoAttributesList;
public class CandidatoPrefAttributes {
private Integer cveCandidato;
private Integer cveCandidatoPreferenciaLaboralEstado;
//More
}
}
public class CandidatoSoftware {
private List<CandidatoSoftwareAttributes> candidatoAttributesList;
public class CandidatoSoftwareAttributes {
private Integer cveCandidato;
private Integer cveCandidatoSoftware;
//More
}
}
}
With respective getters.
Also looks that the candidates (CandidatoPreferenciaLaboralEstado and CandidatoSoftware) and Candidate Preferences are very similar, maybe you can unify that models to one (Candidate and CandidatePrefferences) and use multiple serialized names like:
#SerializedName(value="candidatoPreferenciaLaboralEstado", alternate={"candidatoSoftware"})
Hope this can help you!
I'm using the new firebase sdk for android and use the real database feature. When i use the getValue(simple.class) everything is fine. But when i want to parse a class which is a subclass, all the attribute of the mother class are null, and i have this type of error:
No setter/field for name found on class uk.edume.edumeapp.TestChild
public class TestChild extends TestMother {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
public class TestMother {
protected String motherAttribute;
protected String getMotherAttribute() {
return motherAttribute;
}
}
this function
snapshot.getValue(TestChild.class);
motherAttribute attribute is null, and I get
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
the Json that i parse is:
{
"childAttribute" : "attribute in child class",
"motherAttribute" : "attribute in mother class"
}
Firebaser here
This is a known bug in some versions of the Firebase Database SDK for Android: our serializer/deserializer only considers properties/fields on the declared class.
Serialization of inherited properties from the base class, is missing in the in releases 9.0 to 9.6 (iirc) of the Firebase Database SDK for Android. It was added back in versions since then.
Workaround
In the meantime you can use Jackson (which the Firebase 2.x SDKs used under the hood) to make the inheritance model work.
Update: here's a snippet of how you can read from JSON into your TestChild:
public class TestParent {
protected String parentAttribute;
public String getParentAttribute() {
return parentAttribute;
}
}
public class TestChild extends TestParent {
private String childAttribute;
public String getChildAttribute() {
return childAttribute;
}
}
You'll note that I made getParentAttribute() public, because only public fields/getters are considered. With that change, this JSON:
{
"childAttribute" : "child",
"parentAttribute" : "parent"
}
Becomes readable with:
ObjectMapper mapper = new ObjectMapper();
GenericTypeIndicator<Map<String,Object>> indicator = new GenericTypeIndicator<Map<String, Object>>() {};
TestChild value = mapper.convertValue(dataSnapshot.getValue(indicator), TestChild.class);
The GenericTypeIndicator is a bit weird, but luckily it's a magic incantation that can be copy/pasted.
This was apparently finally fixed in release 9.6.
Fixed an issue where passing a derived class to DatabaseReference#setValue() did not correctly save the properties from the superclass.
for:
No setter/field for motherAttribute found on class uk.edume.edumeapp.TestChild
put setter for TestChild class:
public class TestMother {
private String motherAttribute;
public String getMotherAttribute() {
return motherAttribute;
}
//set
public void setMotherAttribute(String motherAttribute) {
this.motherAttribute= motherAttribute;
}
}
Check this https://firebase.google.com/support/guides/firebase-android
it says
"If there is an extra property in your JSON that is not in your Java class, you will see this warning in the log files: W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage
"
Blockquote
You can get rid of this warning by putting an #IgnoreExtraProperties annotation on your class. If you want Firebase Database to behave as it did in the 2.x SDK and throw an exception if there are unknown properties, you can put a #ThrowOnExtraProperties annotation on your class.
Blockquote
I have the following code which produces the error: Error:Parceler: Unable to find read/write generator for type io.realm.Realm for io.realm.RealmObject.realm
It was working all fine without extends RealmObject , however I want to use Realm to put to database easily. Is there a way to exlcude the RealmObject fields and just use the basic pojo fields for #Parcel?
#Parcel
public class Feed extends RealmObject{
int id;
public String text;
public String time_created;
String time_modified;
int comments_count;
int likes_count;
String feed_type;
int obj_id;
String image;
String user_name;
String user_earthmile_points;
boolean liked;
boolean commented;
boolean is_private;
String url;
int feed_creator_id;
}
EDIT #2: Actually, I found a way to make it work :). See the updated answer below.
EDIT #1: While the app compiles just fine, it crashes when trying to actually create a Parcel with the error: org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for io.realm.FeedRealmProxy. The Realm team has officially acknowledged that it is currently not possible to implement Parcelable on RealmObjects. It is unclear if / when this will be resolved.
With Parceler v0.2.16, you can do this:
#RealmClass // required if using JDK 1.6 (unrelated to Parceler issue)
#Parcel(value = Parcel.Serialization.BEAN, analyze = { Feed.class })
public class Feed extends RealmObject {
// ...
}
Then, use Parcels.wrap(Feed.class, feed) instead of Parcels.wrap(feed) everywhere, otherwise your app will crash with org.parceler.ParcelerRuntimeException: Unable to create ParcelableFactory for io.realm.FeedRealmProxy.
All classes that extend RealmObject will have a matching RealmProxy class created by the annotation processor. Parceler must be made aware of this class. Note that the class is not available until the project has been compiled at least once.
#Parcel(implementations = { PersonRealmProxy.class },
value = Parcel.Serialization.BEAN,
analyze = { Person.class })
public class Person extends RealmObject {
// ...}