BayK
BayK

Reputation: 37

Error Casting Realm Objects as Parcelable

I'm trying to send a Realm object between activities. I've read that using parcelable is the best way to do this. I get a casting error when trying to pass it through an intent though.

Adding @Primary Key created a "Primary key not found" error so I omitted it. Any help would be much appreciated!

My Realm Object class:

@org.parceler.Parcel( implementations = { PersonRealmProxy.class },
value = Parcel.Serialization.BEAN,
analyze = { Person.class })
public class Person extends RealmObject {

private String name;
private int ID;
private String last_name;
private String lots_to_write;
...//getters and setters start here

Passing the Realm Object from MainActivity:

Intent new_ticket = new Intent (MainActivity.this, AllAddedPeople.class );
            new_ticket.putExtra("copyRealm", (Parcelable) myRealm);
            startActivity(new_ticket);

...and receiving it in 2nd Activity:

public class AllAddedPeople extends AppCompatActivity {

private Realm myRealm;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.add_all_people);

    myRealm= (Realm) getIntent().getParcelableExtra("MyClass");

Upvotes: 1

Views: 579

Answers (3)

EpicPandaForce
EpicPandaForce

Reputation: 81588

Okay so your original Y part of the XY problem is that even though you speak of sending the Person object through the intent, you're actually trying to send Realm as is which is not a parcelable, which means it is completely valid for you to get a ClassCastException when you say (Parcelable)realm because it's not parcelable.


The solution to your Y problem is that you're supposed to use Parceler with an unmanaged version of the RealmObject.

@org.parceler.Parcel( /* removing implementations=... */
value = Parcel.Serialization.BEAN,
analyze = { Person.class })
public class Person extends RealmObject {

    // @PrimaryKey // <-- this is obviously missing
    private int ID;

    private String name;
    private String last_name;
    private String lots_to_write;
    ...//getters and setters start here

Then you can do

Intent new_ticket = new Intent (MainActivity.this, AllAddedPeople.class );
        new_ticket.putExtra("person", Parcels.wrap(person.copyFromRealm()));
        startActivity(new_ticket);

Which you can receive like this

private Realm myRealm;
private Person person;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.add_all_people);

    myRealm = Realm.getDefaultInstance();
    // THIS IS WRONG: myRealm = getIntent().getParcelableExtra("MyClass");

    person = Parcels.unwrap(getIntent().getParcelableExtra("person")); // <-- unmanaged person obj.

But this is actually the wrong solution, the solution to your X problem is that you shouldn't be copying RealmObjects from the Realm, and you shouldn't make unmanaged RealmObject instance; they should be re-queried by primary key.

Intent new_ticket = new Intent (MainActivity.this, AllAddedPeople.class );
        new_ticket.putExtra("personId", person.getID());
        startActivity(new_ticket);

And

public class AllAddedPeople extends AppCompatActivity {

    private Realm myRealm;
    private Person person;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_all_people);

        myRealm = Realm.getDefaultInstance();
        person = myRealm.where(Person.class)
                    .equalTo("ID", getIntent().getIntExtra("personId"))
                    .findFirst(); // <-- managed RealmObject
        person.addChangeListener(...

Upvotes: 2

Shashank Srivastava
Shashank Srivastava

Reputation: 446

Intent new_ticket = new Intent (MainActivity.this,AllAddedPeople.class);
            new_ticket.putExtra("copyRealm", (Parcelable) myRealm);
            startActivity(new_ticket);

you don't need to cast your myRealm reference to Parcelable

it should be:

 Intent new_ticket = new Intent (MainActivity.this,AllAddedPeople.class);
                new_ticket.putExtra("copyRealm", myRealm);
                startActivity(new_ticket);

and in other activity

private Realm myRealm;

should be

private MyClass myRealm;

also change

 myRealm= (Realm) getIntent().getParcelableExtra("MyClass");

to

 myRealm= (MyClass) getIntent().getParcelableExtra("MyClass"); 

Upvotes: 0

Sathyajith
Sathyajith

Reputation: 4034

Your Person class should implement the Parcelable interface then you should be ok. Please refer the official document about creating parcelable class https://developer.android.com/reference/android/os/Parcelable.html

Upvotes: 0

Related Questions