Click here to Skip to main content
15,889,825 members
Articles / Mobile Apps / Android
Tip/Trick

Get rid of Parcelable Implemention

Rate me:
Please Sign up or sign in to vote.
3.63/5 (4 votes)
4 Jan 2015CPOL 12.8K   4   4
In this article we will implement a general Parcelable class and name it ParcelableEntity. Then all other entity class can extend it, then they will be parcelable too. So there is no need to implement Parcelable class for other classes.

Introduction

Implementing parcelable class for each entity that we want to pass between activities always was boring for me. So here we will implement it just one time for ever, then our entity classes will extend it and everything is done!

Majesty of reflections will help us.

Background

There are two solution for passing list between activities.

  1. Parcel
  2. Serialize

Here we focus on parcel.

Using the code

First we override writeToParcel method and rewrite it with reflection and looping over each field of entity.

Java
@Override
    public void writeToParcel(Parcel destination, int flags) {

        destination.writeString(this.getClass().getCanonicalName());

        for (Field field : this.getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);
                destination.writeValue(field.get(this));
            } catch (Exception err) {
                Log.w(TAG, err.toString());
            }

        }

    }

And then we implement Creator interface like below.

Java
public static final Creator CREATOR = new Creator() {
        public ParcelableEntity createFromParcel(Parcel source) {
            try {
                Object entity = Class.forName((source.readString())).newInstance();

                for (Field field : entity.getClass().getDeclaredFields()) {
                    try {
                        field.setAccessible(true);
                       field.set(entity, source.readValue(field.getType().getClassLoader()));

                    } catch (Exception err) {
                        Log.w(TAG, err.toString());
                    }
                }

                return (ParcelableEntity) entity;

            } catch (Exception err) {
                return null;
            }
        }

All done!

We save the child class name in the first line of our writeToParcel method because we need it in our createFromParcel method in order to create correct Object from our child class.

Java
//writeToParcel 
destination.writeString(this.getClass().getCanonicalName());

//createFromParcel 
Object entity = Class.forName((source.readString())).newInstance();

and all in one :

Java
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.lang.reflect.Field;
import java.util.ArrayList;

public class ParcelableEntity implements Parcelable {
    private static final String TAG = "ParcelableEntity";

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

    @Override
    public void writeToParcel(Parcel destination, int flags) {

        destination.writeString(this.getClass().getCanonicalName());

        for (Field field : this.getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);
                if (field.getType().equals(java.util.List.class)) {
                    destination.writeList((ArrayList) field.get(this));
                } else
                    destination.writeValue(field.get(this));
            } catch (Exception err) {
                Log.w(TAG, err.toString());
            }

        }

    }

    public static final Creator CREATOR = new Creator() {
        public ParcelableEntity createFromParcel(Parcel source) {
            try {
                Object entity = Class.forName((source.readString())).newInstance();

                for (Field field : entity.getClass().getDeclaredFields()) {
                    try {
                        field.setAccessible(true);
                        if (field.getType().equals(java.util.List.class)) {
                            ArrayList list = new ArrayList();
                            source.readList(list, Class.forName(field.getDeclaringClass().getName()).getClassLoader());
                            field.set(entity, list);
                        } else
                            field.set(entity, source.readValue(field.getType().getClassLoader()));

                    } catch (Exception err) {
                        Log.w(TAG, err.toString());
                    }
                }

                return (ParcelableEntity) entity;

            } catch (Exception err) {
                return null;
            }
        }

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

}

and how to use our class :

1- Our entity class will extent above class :

Java
public class Book extends ParcelableEntity {

    public Long id;
    public String name;
}

2- Call destination activity :

Java
public void onClick(View view) {
        ArrayList<book> lstBook = new ArrayList<>();
        Book b1 = new Book();
        b1.id = 1L;
        b1.name = "test 1";
        lstBook.add(b1);
        Book b2 = new Book();
        b2.id = 2L;
        b2.name = "test 2";       
        lstBook.add(b2);

        Intent intent = new Intent(MainActivity.this, SecondActivity.class);
        intent.putParcelableArrayListExtra("TEST", lstBook);
        startActivity(intent);
    }
</book>

3- Geting extra in destination activity

Java
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        Bundle extras = getIntent().getExtras();
        List<book> lstBook = extras.getParcelableArrayList("TEST");
    }
</book>

Thanks.

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionIncomplete Pin
phil.o5-Jan-15 4:36
professionalphil.o5-Jan-15 4:36 
GeneralMy vote of 2 Pin
Klaus Luedenscheidt4-Jan-15 17:30
Klaus Luedenscheidt4-Jan-15 17:30 
GeneralRe: My vote of 2 Pin
farhad21614-Jan-15 18:09
farhad21614-Jan-15 18:09 
GeneralRe: My vote of 2 Pin
Klaus Luedenscheidt5-Jan-15 17:32
Klaus Luedenscheidt5-Jan-15 17:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.