5
votes

I'm used to develop in ios where I never need to make a model parcelable so the concept is not very clear to me. I have a class "game" like:

//removed the method to make it more readable.
public class Game implements Parcelable {
    private int _id;
    private ArrayList<Quest> _questList;
    private int _numberOfGames;
    private String _name;
    private Date _startTime;

    public Game(String name, ArrayList<Quest> quests, int id){
        _name = name;
        _questList = quests;
        _numberOfGames = quests.size();
        _id = id;
    }
}

I want to start an activity and pass the game object to the activity with my intent, but it turned out you can't pass custom objects by default but they need to be parcelable. So I've added:

public static final Parcelable.Creator<Game> CREATOR
        = new Parcelable.Creator<Game>() {
    public Game createFromParcel(Parcel in) {
        return new Game(in);
    }

    public Game[] newArray(int size) {
        return new Game[size];
    }
};
private Game(Parcel in) {
    _id = in.readInt();
    _questList = (ArrayList<Quest>) in.readSerializable();
    _numberOfGames = in.readInt();
    _name = in.readString();
    _startTime = new Date(in.readLong());
}

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

@Override
public void writeToParcel(Parcel out, int flags) {
    out.writeInt(_id);
    out.writeSerializable(_questList);
    out.writeInt(_numberOfGames);
    out.writeString(_name);
    out.writeLong(_startTime.getTime());
}

But now I get the warning that the custom arraylist _questList is not parcelable Game.

Quest is an abstract class so it cant implement.

   public static final Parcelable.Creator<Game> CREATOR = new Parcelable.Creator<Game>() {
    public Game createFromParcel(Parcel source) {
        return new Game(source);
    }

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

So my question is: When do I need to implement parcelable, do I have to add it to every custom object I want to pass (even if in another custom object)? I can't imagine they don't have something easier for android to pass a custom object with an array list of custom objects.

2
I suggest you using Android Parcerable Generator: github.com/mcharmas/android-parcelable-intellij-plugindominik4142
@dominik4142 is parcelable to only way possible?Sven van den Boogaart
There is a couple of approaches to that. Simplest: you can either store this data in Application singleton which preserves its state through all app life or store it in database and pass between activities only some kind of identifier. Passing rich objects through activities is not recommended because it makes screen rotations, going between screens really slow.dominik4142
Storing data in application object is bad idea and I do not recommend it instead of doing Parcelable properlyMarcin Orlowski
Quest needs to be parcelable. And you should use writeTypedList. If you want to be god tier, you can use Mortar and mortar scope for your application, and a subscope for your game to store its data. A quick database to use with an id is Realm. You have many approaches.EpicPandaForce

2 Answers

2
votes

As you already discovered if you want to send own data via Intent you need to make it possible. On Android it's recommended to use Parcelable. You may implement this interface yourself or use existing tools like Parceler or Parcelable Please. Note: these tools comes with some limitation so ensure you know them as sometimes it may be cheaper to implement Parcelable by hand instead of writing code to work it around.

is parcelable to only way possible

No. You can use Serializable (also with Parcels), but Parcelable is the way to go on Android as it is faster and it is how it's done on platform level.

1
votes

Let's say Parcelable is something like Optimized Serializable, designed for Android and Google recommends to use Parcelable over Serializable. Android OS uses Parcelable iteself (for example: SavedState for Views). Implementing Parcelable by hand is a bit of pain, so there are some helpful solutions:

  • Android Parcerable Generator. IntelliJ plugin which implements Parcelable stuff for you (adds constructor, CREATOR inner class, implements methods etc.) for your data class. You can get it here. enter image description here

  • Parceler. Annotation-based code generation framework. You have to use @Parcel annotation for you data class, and some helper methods. More info here. enter image description here

  • Parcelable Please. Annotation-based code generation framework shipped along with the IntelliJ plugin. I wouldn't recommend using it since it's not maintained for 1 year.

Personally i use 1st solution since it's fast, easy and no need to mess with annotations and workarounds.

You may want to read this article.