Search code examples
javaandroidparcelable

Using GSON for generic Parcelable -- how to retrieve class type


Caveat

There may be an easier / smarter way to do this. I'm not a good Android developer. Please advise

Problem

I have a library with about 100 different models. I now have to make all of these models parcelable.

Rather than implement writeToParcel for every single one, I thought it would be nice if I could just create a super class that used generic serialization logic. Something like the following:

public abstract class Model implements Parcelable
{

    public final static Parcelable.Creator<Model> CREATOR = new Parcelable.Creator<Model>() {
        @Override
        public Model createFromParcel ( Parcel parcel )
        {
            Gson gson = new Gson();
            String type = parcel.readString();
            String serialized = parcel.readString();
            gson.fromJson(serialized, /* HELP ME */)
        }

        @Override
        public Model[] newArray ( int i )
        {
            // TODO: I haven't even read the docs on this method yet
        }
    };

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

    @Override
    public void writeToParcel ( Parcel parcel, int i )
    {
        Gson gson = new Gson();
        String type = this.getClass().getName();
        String serialized = gson.toJson(this);
        parcel.writeString(type);
        parcel.writeString(serialized);
    }

}

Then in each of my models I just say:

public class Whatever extends Model {

The problem is that Gson requires me to provide Type in order to de-serialize. How can I get this Type value? As you can see, I tried using this.getClass().getName() to get the name of the class, but I have no idea how to reverse this and go from a string back to a type. I also don't fully understand the difference between Class<T> and Type.


Solution

  • I solved this by using:

    String type = this.getClass().getCanonicalName();
    

    to get the type, and then:

    return (Model) gson.fromJson(serialized, Class.forName(type));
    

    in my createFromParcel method