7

i need to implement the Parcelable interface in a Realm model but i have no idea how to write a RealmList in a Parcel

here is my code:

public class SomeModel extends RealmObject implements Parcelable {
  public long id;

  public RealmList<SomeOtherModel> otherModels;

  protected SomeModel(Parcel in) {
   id = in.readLong();
   //here i need to otherModel RealmList from parcel
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeLong(id);
    // here i need to write the otherModels RealmList
  }
  //other methods omitted 
}

pd: the SomeOtherModel class also implements the Parcelable interface and extends RealmObject

Spaceghost87
  • 85
  • 1
  • 7
  • https://gist.github.com/Rexee/3ec92b759b3a944d4ad4b28666b2479c although I hope it's not for sending objects between activities using intent. – EpicPandaForce Apr 25 '17 at 19:59
  • this solution relies on this library https://github.com/johncarl81/parceler, i don't want to add yet another gradle dependency to my project, i need something using just the android SDK, but thanks anyway – Spaceghost87 Apr 25 '17 at 20:03
  • well. Good luck, considering you can't modify `RealmList` to have a CREATOR or be parcelable. What is your use-case? – EpicPandaForce Apr 25 '17 at 20:04
  • my use case is: i need to validate all fields before save this object in realm, so i need it in memory until the validation is done, so i need to use a bundle with a parcelable object in order to retain this object before the validation – Spaceghost87 Apr 25 '17 at 20:09
  • A reasonable use-case. But I have to point you towards either Parceler, or to serializing the object to JSON and back. – EpicPandaForce Apr 25 '17 at 20:18

3 Answers3

21

Actually you can

Firstly we are talking about un-managed entities.

Then you need to initialize realmList with new RealmList<>() . Then add data to it as collection with addAll method.That's it! Here is a sample:

Person.java:

package com.entity;

import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;

import io.realm.RealmList;

/**
 * Person
 * Created by Maher Abuthraa on 6/9/17.
 */

public class Person implements Parcelable {
    @PrimaryKey
    private long id;

    private String name;
    private RealmList<Dog> mRealmList;

    public Person() {
    }

    public Person(long id, String name) {
        this.id = id;
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public Person setId(long id) {
        this.id = id;
        return this;
    }

    public String getName() {
        return name;
    }

    public Person setName(String name) {
        this.name = name;
        return this;
    }

    public RealmList<Dog> getRealmList() {
        return mRealmList;
    }

    public Person setRealmList(ArrayList<Dog> dogList) {
        mRealmList = new RealmList<>();
        mRealmList.addAll(dogList);
        return this;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeString(this.name);
        dest.writeTypedList(this.mRealmList);
    }

    protected Person(Parcel in) {
        this.id = in.readLong();
        this.name = in.readString();
        this.mRealmList = new RealmList<>();
        this.mRealmList.addAll(in.createTypedArrayList(Dog.CREATOR));
    }

    public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
}

Dog.java:

package com.entity;

import android.os.Parcel;
import android.os.Parcelable;

import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;

/**
 * Dog
 * Created by Maher Abuthraa on 6/9/17.
 */

public class Dog extends RealmObject implements Parcelable {
    @PrimaryKey
    private long id;

    private String name;
    private int age;

    public Dog() {
    }

    public Dog(long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public long getId() {
        return id;
    }

    public Dog setId(long id) {
        this.id = id;
        return this;
    }

    public String getName() {
        return name;
    }

    public Dog setName(String name) {
        this.name = name;
        return this;
    }

    public int getAge() {
        return age;
    }

    public Dog setAge(int age) {
        this.age = age;
        return this;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }

    protected Dog(Parcel in) {
        this.id = in.readLong();
        this.name = in.readString();
        this.age = in.readInt();
    }

    public static final Parcelable.Creator<Dog> CREATOR = new Parcelable.Creator<Dog>() {
        @Override
        public Dog createFromParcel(Parcel source) {
            return new Dog(source);
        }

        @Override
        public Dog[] newArray(int size) {
            return new Dog[size];
        }
    };
}

I hope that may help,'.

Maher Abuthraa
  • 17,493
  • 11
  • 81
  • 103
  • This answer should be marked as correct answer! Thank you sir! – Banana droid Jun 12 '17 at 05:31
  • what if the object is Double or String, How should I write this line. this.mRealmList.addAll(in.createTypedArrayList(Dog.CREATOR)); – Nabeel K Nov 20 '17 at 10:21
  • 1
    @NabeelK, you have at least three options: best to use RealmList (new support added to 4.0.0. ) so RealmList can include (String, byte[], Boolean, Long, Integer, Short, Byte, Double, Float, and others ), or map primitive data value into another RealmObject (Bonus you'd get ID which allow you to share it) or you might hash it under string, and extract it later.( I recommend 1st solution instead of this ) – Maher Abuthraa Nov 20 '17 at 10:40
  • Thanks @MaherAbuthraa let me try. – Nabeel K Nov 20 '17 at 10:52
2

You won't be able to easily make a RealmList parcelable, you should either convert it to JSON and parcel it as a string, or use Parceler library with this gist. I think JSON with your custom adapter is actually more reliable, though.

EDIT: with Kotlin, you can follow this approach.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
0

I think it's not possible to make RealmObject parcelable. But if I understand your case right, you can use copyFromRealm() method to detach object from Realm and do whatever you want with it.

Svoka
  • 39
  • 2