Realm-java: Document Realm compatibility with Parceler

Created on 23 Jun 2015  路  18Comments  路  Source: realm/realm-java

Hi

I have a Realm object that is also Parcelable. I use Parceler as a workaround because it's not possible to implement Parcelable on Realm objects. Everything has been working nicely so far, but I ran into a problem when I tried to launch an activity with ACTION_SEND set on the intent.

This is the Parceler exception I'm getting (logged a bug for them here https://github.com/johncarl81/parceler/issues/106):

org.parceler.ParcelerRuntimeException: Unable to find generated Parcelable class for io.realm.MessageRealmProxy, verify that your class is configured properly and that the Parcelable class io.realm.MessageRealmProxy$$Parcelable is generated by Parceler.
           at org.parceler.Parcels$ParcelCodeRepository.get(Parcels.java:201)
           at org.parceler.Parcels.wrap(Parcels.java:85)
           at org.parceler.Parcels.wrap(Parcels.java:69)
           at org.parceler.NonParcelRepository$ListParcelable$1.itemToParcel(NonParcelRepository.java:280)
           at org.parceler.converter.CollectionParcelConverter.toParcel(CollectionParcelConverter.java:38)
           at org.parceler.converter.CollectionParcelConverter.toParcel(CollectionParcelConverter.java:27)
           at org.parceler.NonParcelRepository$ConverterParcelable.writeToParcel(NonParcelRepository.java:1222)
           at org.parceler.NonParcelRepository$ListParcelable.writeToParcel(NonParcelRepository.java:269)
           at android.os.Parcel.writeParcelable(Parcel.java:1357)
           at android.os.Parcel.writeValue(Parcel.java:1262)
           at android.os.Parcel.writeArrayMapInternal(Parcel.java:638)
           at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313)
           at android.os.Bundle.writeToParcel(Bundle.java:1096)
           at android.os.Parcel.writeBundle(Parcel.java:663)
           at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:137)
           at android.os.Parcel.writeTypedArray(Parcel.java:1191)
           at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:384)
           at android.os.Parcel.writeParcelable(Parcel.java:1357)
           at android.os.Parcel.writeValue(Parcel.java:1262)
           at android.os.Parcel.writeArrayMapInternal(Parcel.java:638)
           at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313)
           at android.os.Bundle.writeToParcel(Bundle.java:1096)
           at android.os.Parcel.writeBundle(Parcel.java:663)
           at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2901)
           at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3290)
           at android.os.Handler.handleCallback(Handler.java:739)
           at android.os.Handler.dispatchMessage(Handler.java:95)
           at android.os.Looper.loop(Looper.java:135)
           at android.app.ActivityThread.main(ActivityThread.java:5254)
           at java.lang.reflect.Method.invoke(Native Method)
           at java.lang.reflect.Method.invoke(Method.java:372)
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

The realm object is called Message and is set to be parcelable using the following annotation:

@RealmClass
@Parcel(implementations = { Message.class }, value = Parcel.Serialization.BEAN, analyze = { Message.class })
public class Message extends RealmObject {

The class is not just a simple POJO, it has some static methods that parses data and some of the member variables are set as @Ignore, but I've tried simplifying it, and I still get the same error.

T-Doc

All 18 comments

Update: Managed to solve the issue

After reading through https://github.com/johncarl81/parceler/issues/57 I saw that you have to add

implementations = { MyObjectRealmProxy.class }

to the Parceler annotation

e.g.

@Parcel(implementations = { MyObjectRealmProxy.class }, value = Parcel.Serialization.BEAN, analyze = { MyObject.class })

Hi @LaurieScheepers
Thank you for pointing us to this. We should probably document this on our website so others don't have to search for it.

Ah, is MyObjectRealmProxy a generated class by Realm?

Yes. That is our wrapper class for your model class. That is whats get returned when you call realm.createObject() or realm.copyToRealm()

Great, adding the proxy class t the implementations parameter is the proper technique. Essentially this adds it as an alternate when looking up the Parcelable wrapper class in the Parcels utility.

Working with Parceler is pretty straightforward using the above configuration, but RealmList is currently not supported. See https://github.com/johncarl81/parceler/issues/107

I believe we should be able to support the RealmList.

Yes, it seems to be possible. We should update our documentation to reflect that. The complete solutions is also posted here: https://github.com/johncarl81/parceler/issues/107#issuecomment-121585255

Documentation has been updated with instructions for working with Parceler 1.0.3

Other than using the Parceler library, is there a way I can implement parcelable?

Currently no. Another possibility is to parse a primary key through a parcel and then requery the object on the other side.

thanks for the answer cmelchior, i dont want to use the parceler library since i am already using enough libraries as it is, besides it seems to have some issue with android annotations lol , how about the main class extending realmObject and a subclass that implements parcelable, would that kind of stuff work, there must be some way,i read somewhere in one of the issues where you mentioned, currently you ll have to duplicate your models, one that has Realm and one that has parcelable, if I want to do this [obviously a very bad solution but i love your lib and dont wanna stop using that either :) ] what do you think is the best way i can approach the duplication?

For the record, Parceler works just fine with Android Annotations. Here's an example: http://stackoverflow.com/a/29691052/654187
If you know of a problem @slidenerd please post it on the Parceler issues list so it can be addressed.

How can I import the *RealmProxy classes?

@mateusgrb, from what I understand, the RealmProxy classes are generated at compile time. They should be available after the first build. Also, you shouldn't have to import them as they will exist under the same package.

@johncarl81 Thanks for the answer. I found them under the build folder(using Find File tool in Android Studio), but can't import. And if I don't import them, I get a compile error if I try something like "implementations = { MyObjectRealmProxy.class }".

Is this a compile error in your command line build (perhaps with gradle?) or in the IDE?

Haha I came across this now randomly almost 2 years later, after wanting to do the same thing again in a new project and realized I was the one who originally started this discussion. Glad to have helped. And to have helped myself. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CNyezi picture CNyezi  路  3Comments

Frasprite picture Frasprite  路  3Comments

bryanspano picture bryanspano  路  3Comments

AAChartModel picture AAChartModel  路  3Comments

harshvishu picture harshvishu  路  3Comments