Thursday, May 21, 2015

Android parcelable tutorial: List and inner class

Advanced Parcel data in Android: how to parcel complex data structure like java List and inner class

Topics covered

Android Parcelable

Android Parcelable List

Android Parcelable inner class

When we want to pass objects between two components in Android, these objects have to implements Parcelable interface.Parcelable Android is a serialization and deserialisation mechanism as we are used in Java. This post describes how we can use Parcelable interface to pass objects between two Android Activity.
We talked about some basic concepts of Parcelable in Android, in this post we will analyse some more complex example and we will look how we can parcel a List of objects or parcel a class that contains inner class.

Android parcelable tutorial using class and list


Android Parcel object

We know that if we want that Android OS can "serialize" an object it must implement Parcelable interface. To make an object parcelable we have to implements two methods defined in Android Parcelable interface:
Moreover, we have to provide Parcelable.Creator that is used to create an instance of the class from the Parcel data.
So let us suppose we have a simple class that contains a contact info:

public class ContactInfo {

private String name;
private String surname;
private int idx;

// get and set methods
}

So to make this object parcelable we have:

public class ContactInfo implements Parcelable {

private String name;
private String surname;
private int idx;

// get and set method

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

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(surname);
dest.writeInt(idx);
}

// Creator
public static final Parcelable.Creator CREATOR
= new Parcelable.Creator() {
public ContactInfo createFromParcel(Parcel in) {
return new ContactInfo(in);
}

public ContactInfo[] newArray(int size) {
return new ContactInfo[size];
}
};

// "De-parcel object
public ContactInfo(Parcel in) {
name = in.readString();
surname = in.readString();
idx = in.readInt();
}
}



As you can notice we have implemented all the requested method. So the parcel operation is very simple because in the writeToParcel method we simply write all the class attributes and in the Parcel.Creator we read the parcel data. The creator calls a constructor passing Parcel object and here in the constructor we initialise the class attributes.
So now we are ready to pass this object from a caller activity to a receiver activity: in this case the in the caller activity (MainActivity):

Intent i = new Intent(MainActivity.this, ActivityB.class);
// Contact Info
ContactInfo ci = createContact("Francesco", "Surviving with android", 1);
i.putExtra("contact", ci);

while in the receiver activity we have:

Intent i  = getIntent();
ContactInfo ci = i.getExtras().getParcelable("contact");
tv.setText(ci.toString()); // tv is a TextView instance

android development tutorialandroid bundle example

Android Parcelable List

By now, we used a simple example, now we want to create something more complex. Instead using a simple class, we parcel a list of contact.
Now we have that our class is already parcelable, so it is simple; in the caller activity we have:


List%lt;ContactInfo> cList = createContactList();
i.putParcelableArrayListExtra("contact", (ArrayList) cList);

while in the called activity:

List<ContactInfo> ciArr = (List) i.getParcelableArrayListExtra("contact");

Android Parcel inner class

To parcel an class that contains an inner class we have to modify slightly the code. For example, let us suppose we have a inner class in our ContactInfo that contains the address:

public class ContactInfo implements Parcelable {

private String name;
private String surname;
private int idx;
private Address address;

...
// Inner class
public static class Address {
private String street;
private String city;
private int number;

// get and set methods
}
}

Now, the first thing is making the inner class parcel able:

   // Inner class
public static class Address implements Parcelable {
private String street;
private String city;
private int number;

public Address() {}


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

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(street);
dest.writeString(city);
dest.writeInt(number);
}

// Creator
public static final Parcelable.Creator

CREATOR
= new Parcelable.Creator

() {
public Address createFromParcel(Parcel in) {
return new Address(in);
}

public Address[] newArray(int size) {
return new Address[size];
}
};

// "De-parcel object
private Address(Parcel in) {
street = in.readString();
city = in.readString();
number = in.readInt();
}
}



Notice that the inner class is now static otherwise it is not parcelable, second in the outer class:
public class ContactInfo implements Parcelable {

private String name;
private String surname;
private int idx;
private Address address;

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

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(surname);
dest.writeInt(idx);

// Add inner class
dest.writeParcelable(address, flags);
}

// "De-parcel object
public ContactInfo(Parcel in) {
name = in.readString();
surname = in.readString();
idx = in.readInt();

address = (Address) in.readParcelable(Address.class.getClassLoader());
}


At line 30 to unparcel the inner class we used the class loader
Running the example, we have:

how to use parcelable interface to parcel class holding inner class

Source code available @github

In this post, you gained a knowledege about parcel concept in android and how to use it to pass data.

Android parcelable tutorial: List and inner class Rating: 4.5 Diposkan Oleh: Unknown

0 comments:

Post a Comment