Correct way of implementing Parcelable

2k views Asked by At

What is the correct way of implementing the Parcelable interface in Android? According to the documentation you should implement the writeToParcel method and have a CREATOR.

public void writeToParcel(Parcel out, int flags) {
     out.writeInt(mData);
 }

But when I implement it without adding a CREATOR and leaving the writeToParcel() empty the app still seems to work correctly. Sometimes I would get a Bad Parcelable Exception but I can't work out the steps to replicate.

This is how I use to pass an object from activity to fragment

 Bundle bundle = new Bundle();
 bundle.putParcelable(PageFragment.PAGE_FILTER_KEY, page);
 fragment.setArguments(bundle);

So, what is the purpose of adding stuff like out.writeInt(mData); what kind of problems can be expected if this is not done?

2

There are 2 answers

0
Mahendra Chhimwal On BEST ANSWER

Parcelable implementation mainly have two process steps.

1 Writing your java object to Parcel which includes two methods.

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(cityName);
        dest.writeString(macroName);
        dest.writeString(id);
    }

where describe content is for setting a flag for your contents. Most of time you just need to it untouched.

public void writeToParcel(Parcel dest, int flags) , you need to write you Java class object to parcel step by step according to fields in JAVA class. In above example my class has three strings. You can write almost all types of objects in parcel. You just need to chose appropriate one. Like writeString(),writeList() or writeObject() etc.

2. Second part is reading your java object back from parcel

This part required two things as well. First is CREATOR of your java class like following

 public static final Creator<City> CREATOR = new Creator<City>() {
        @Override
        public City createFromParcel(Parcel in) {
            return new City(in);
        }

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

In above example my Java class is City. It makes read a City object from parcel. But it calls new City(in) constructor of City class. So now I need a constructor which accept a parcel object in arguments. Lets create that too..

 protected City(Parcel in) {
        cityName = in.readString();
        macroName = in.readString();
        id = in.readString();
    }

Now we make a class complete full proof parcelable. One thing to notice, we need to read members in same sequence at protected City(Parcel in) we put them in parcel i.e. in writeToParcel() method.

On how to reproduce badParcelable exeption in simply letting android create java object from parcelable. For that you can choose Destroy activities from developer options on android device and put you app in background in that activity, so android kill your application process ID. Resume your app by recreating activity (onCreate + Bundle), you will get that exception if you does not implemented parcelable correctly.

2
CommonsWare On

But when I implement it without adding a CREATOR and leaving the writeToParcel() empty the app still seems to work correctly.

CREATOR is used when reading data back out of a Parcel and converting it back into objects.

writeToParcel() puts your data into the Parcel.

The only way that leaving those off will work correctly is in cases where your Parcelable is not actually being put into a Parcel or reconstituted from a Parcel. Examples include LocalBroadcastManager.

what is the purpose of adding stuff like out.writeInt(mData);

It would be the same purpose as adding stuff like out.write() with an OutputStream: it writes to the output. Your question is akin to asking "hey, if I don't write data to my file, what sorts of problems will I encounter?".