Parcelable

Maciej Górski edited this page May 22, 2014 · 3 revisions

Parcelable annotation is used to generate all the boilerplate code you would normally write for classes implementing android.os.Parcelable.

Usage

Now you can write

import hrisey.Parcelable;

@Parcelable
public final class MyClass implements android.os.Parcelable {

    private double myDouble;
    private int myInt;
}

instead of

import android.os.Parcel;
import android.os.Parcelable;

public final class MyClass implements Parcelable {

    private double myDouble;
    private int myInt;

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeDouble(this.myDouble);
        dest.writeInt(this.myInt);
    }

    MyClass(Parcel source) {
        this.myDouble = source.readDouble();
        this.myInt = source.readInt();
    }

    public static final Parcelable.Creator<MyClass> CREATOR = new Parcelable.Creator<MyClass>() {

        @Override
        public MyClass createFromParcel(Parcel source) {
            return new MyClass(source);
        }

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

Details

Hrisey generates very efficient code, avoiding certain Parcel methods (e.g. writeList, writeMap), which store full class name of marshalled objects alongside relevant bits for those objects.

Currently supported types:

  • boolean and Boolean,
  • byte and Byte,
  • double and Double,
  • float and Float,
  • int and Integer,
  • long and Long,
  • String,
  • implementing Parcelable (or annotated),
  • Bundle
  • IBinder,
  • BooleanSparseArray,
  • generic List and subtypes:
    • ArrayList,
    • LinkedList,
  • generic Set and subtypes:
    • HashSet,
    • LinkedHashSet,
    • TreeSet,
  • generic Map and subtypes:
    • HashMap,
    • LinkedHashMap,
    • TreeMap
  • char[],
  • arrays of supported types
  • arrays of arrays of supported types
  • arrays of arrays of arrays of supported types, etc.

When all else fails, Parcel.writeValue is used.

Hints

  1. Whenever possible, add final to your Parcelable classes. This way you will have generated code more efficient in terms of memory and cpu use.
  2. If you use List, Map or Set, they are unmarshalled to ArrayList, HashMap and HashSet respectively. If you need a different implementation, just define your fields types. For example when you want to keep order of elements in a Map, use LinkedHashMap.
  3. Adding implements android.os.Parcelable to a class annotated with @Parcelable is not necessary. Due to a limitation in code augmentation in Hrisey IntelliJ Plugin, it is better to have it if you don't like red highlights. The code will compile both ways.
  4. Curious about how generated code looks like? Take a look at files starting with Parcelable in before and after.

Works well with

  • @Value
  • @Builder
  • @Wither