Using Android Parcelable Objects

Parcelable is an Android interface that you can use to create parcelable objects. The idea of a parcelable object Android is similar to Serialization in core Java. The differences are the parcelable is more optimized to pass data between activties or fragments in Android, so it is much faster than serialization. A parcelable object does the marshaling and unmarshaling of the data to avoid creating garbage objects.

When implementing a Parcelable interface for a model class, the required methods to implement are describeContents(), writeToParcel() and a constructor with Parcel as the only one parameter, plus a Parcelable.Creator declared as public static final.

The constructor with the Parcel parameter reads the data from Parcel and save it to the class properties. The method writeToParcel as the name suggests, it writes the data to the Parcel for data delivery. One important thing to remember is, the order of the read and write has to be the same in the constructor and the writeToParcel method. For example, if you read string1 first, string2 second and then string3 in the constructor, you have to write string1 first, string2 second and then string3 in the writeToParcel method.

A simple Parcelable class with only primitive data fields, Major.java

public class Major implements Parcelable {
    private String mSubject;
    private int mGradeMinimum;

    public Major(String subject, int gradeMinimum) {
        this.mSubject = subject;
        this.mGradeMinimum = gradeMinimum;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.mSubject);
        dest.writeInt(this.mGradeMinimum);
    }

    protected Major(Parcel in) {
        this.mSubject = in.readString();
        this.mGradeMinimum = in.readInt();
    }

    public static final Creator<Major> CREATOR = new Creator<Major>() {
        public Major createFromParcel(Parcel source) {
            return new Major(source);
        }
        public Major[] newArray(int size) {
            return new Major[size];
        }
    };

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //The following are just setter and getter methods
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    public String getmSubject() {
        return mSubject;
    }
    public void setmSubject(String mSubject) {
        this.mSubject = mSubject;
    }
    public int getmGradeMinimum() {
        return mGradeMinimum;
    }
    public void setmGradeMinimum(int mGradeMinimum) {
        this.mGradeMinimum = mGradeMinimum;
    }
}

A Parcelable class with a Parcelable object as one of the data field. This kind of Parcelable class is also called nested parcelable class. Student.java, the special lines are dest.writeParcelable(this.mMajor, flags); and this.mMajor = in.readParcelable(Major.class.getClassLoader());. Important to remember: The parcelable object has to be the first one in the read and write

/**
 * Nested Parcelable Example
 * The nested parcelable object: Major
 *
 * The differences from simple parcelable class:
 * The parcelable object has to be the first one in the read and write
 *
 * write: dest.writeParcelable(this.mMajor, flags);
 * read: this.mMajor = in.readParcelable(Major.class.getClassLoader());
 */
public class Student implements Parcelable {
	
	private String mName;
	private String mEmail;
	private int mAge;
	private Major mMajor;

	public Student(String sName, String sEmail, int sAge, Major major) {
		this.mName = sName;
		this.mEmail = sEmail;
		this.mAge = sAge;
		this.mMajor = major;
	}

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

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		//The parcelable object has to be the first one
		dest.writeParcelable(this.mMajor, flags);
		dest.writeString(this.mName);
		dest.writeString(this.mEmail);
		dest.writeInt(this.mAge);
	}

	protected Student(Parcel in) {
		// The order of the properties has to be the same in the writeToParcel method
		this.mMajor = in.readParcelable(Major.class.getClassLoader());
		this.mName = in.readString();
		this.mEmail = in.readString();
		this.mAge = in.readInt();
	}

	public static final Creator<Student> CREATOR = new Creator<Student>() {
		public Student createFromParcel(Parcel source) {
			return new Student(source);
		}
		public Student[] newArray(int size) {
			return new Student[size];
		}
	};


    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //The following are just setter and getter methods
    //////////////////////////////////////////////////////////////////////////////////////////////////////
	public String getEmail() {
		return mEmail;
	}
	public void setEmail(String mSEmail) {
		this.mEmail = mSEmail;
	}
	public String getName() {
		return mName;
	}
	public void setName(String mSName) {
		this.mName = mSName;
	}
	public int getAge() {
		return mAge;
	}
	public void setAge(int mSAge) {
		this.mAge = mSAge;
	}
	public Major getmMajor() {
		return mMajor;
	}
	public void setmMajor(Major mMajor) {
		this.mMajor = mMajor;
	}
}

A Parcelable class with one of the class field being an ArrayList of another Parcelable objects. Teacher.java, a teacher can have multiple students. The special lines are dest.writeTypedList(this.mStudents); and in.readTypedList(this.mStudents, Student.CREATOR);

/**
 * List of Parcelables in a Parcelable Example
 * The list of parcelables: ArrayList<Student>
 *
 * The differences from simple parcelable class:
 * write: dest.writeTypedList(this.mStudents);
 * read: in.readTypedList(this.mStudents, Student.CREATOR);
 */
public class Teacher implements Parcelable {

	private String mName;
	private String mEmail;
	private int mAge;
	private ArrayList<Student> mStudents = new ArrayList<>();

	public Teacher(String sName, String sEmail, int sAge, ArrayList<Student> students) {
		this.mName = sName;
		this.mEmail = sEmail;
		this.mAge = sAge;
		this.mStudents = students;
	}

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

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeString(this.mName);
		dest.writeString(this.mEmail);
		dest.writeInt(this.mAge);

		dest.writeTypedList(this.mStudents);
	}

	protected Teacher(Parcel in) {
		this.mName = in.readString();
		this.mEmail = in.readString();
		this.mAge = in.readInt();

		in.readTypedList(this.mStudents, Student.CREATOR);
	}

	public static final Creator<Teacher> CREATOR = new Creator<Teacher>() {
		public Teacher createFromParcel(Parcel source) {
			return new Teacher(source);
		}
		public Teacher[] newArray(int size) {
			return new Teacher[size];
		}
	};



    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //The following are just setter and getter methods
    //////////////////////////////////////////////////////////////////////////////////////////////////////
	public int getAge() {
		return mAge;
	}

	public void setAge(int mSAge) {
		this.mAge = mSAge;
	}

	public String getEmail() {
		return mEmail;
	}

	public void setEmail(String mSEmail) {
		this.mEmail = mSEmail;
	}

	public String getName() {
		return mName;
	}

	public void setName(String mSName) {
		this.mName = mSName;
	}

	public ArrayList<Student> getStudents() {
		return mStudents;
	}

	public void setStudents(ArrayList<Student> mStudents) {
		this.mStudents = mStudents;
	}
}

Create some dummy Parcelable object using the above Parcelable classes.

ArrayList<Student> students = new ArrayList<>();
students.add(new Student("Amy", "amy@test.com", 18, new Major("Biology", 90)));
students.add(new Student("Ben", "ben@test.com", 18, new Major("Chemistry", 90)));

Teacher teacher = new Teacher("Aristotle", "aristotle@test.com", 30, students);

To pass the above student parcelable to an activity class, for example AnStudentViewActivity class

Intent intent = new Intent(getBaseContext(), AnStudentViewActivity.class);
intent.putExtra("student", student);
startActivity(intent);

To get student parcelable in the AnStudentViewActivity class, in the onCreate method

Student student = getIntent().getParcelableExtra("student");

Complete example in Github

Search within Codexpedia

Custom Search

Search the entire web

Custom Search