In Android, Parcelables are a great way to serialize Java Objects between Contexts.
Compared with traditional Serialization, Parcelables take on the order of 10x less time to both serialize and deserialize.
There is a major flaw with Parcelables, however.
Parcelables contain a ton of boilerplate code.
To implement a Parcelable, you must mirror the writeToParcel() and createFromParcel() methods such that they read and write to the Parcel in the same order.
Also, a Parcelable must define a public static final Parcelable.Creator CREATOR in order for the Android infrastructure to be able to leverage the serialization code.
Parceler is a code generation library that generates the Android Parcelable boilerplate source code.
No longer do you have to implement the Parcelable interface, the writeToParcel() or createFromParcel() or the public static final CREATOR.
You simply annotate a POJO with @Parcel and Parceler does the rest.
Because Parceler uses the Java JSR-269 Annotation Processor, there is no need to run a tool manually to generate the Parcelable code.
Just annotate your Java Bean, compile and you are finished.
By default, Parceler will serialize the fields of your instance directly:
@Parcel
public class Example {
String name;
int age;
public Example() {}
public Example(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
}
Be careful not to use private fields when using the default field serialization strategy as it will incur a performance penalty due to reflection.
To use the generated code, you may reference the generated class directly, or via the Parcels utility class:
Parcelable wrapped = Parcels.wrap(new Example("Andy", 42));
To dereference the @Parcel, just call the Parcels.unwrap() method:
Example example = Parcels.unwrap(wrapped);
example.getName(); // Andy
example.getAge(); // 42
Of course, the wrapped Parcelable can be added to an Android Bundle to transfer from Activity to Activity:
Bundle bundle = new Bundle();
bundle.putParcelable("example", Parcels.wrap(example));
And dereferenced in the onCreate() method:
Example example = Parcels.unwrap(getIntent().getParcelableExtra("example"));
This wrapping and unwrapping technique plays well with the Intent Factory pattern.
In addition, Parceler is supported by the following libraries:
-
Transfuse - Allows @Parcel annotated beans to be used with the @Extra injection.
-
FragmentArgs - Uses the ParcelerArgsBundler adapter to wrap and unwrap @Parcel annotated beans with fragment parameters.
-
Dart - Autodetects @Parcel annotated beans and automatically unwraps them when using @InjectExtra.
-
AndroidAnnotations - Autodetects @Parcel annotated beans and automatically wraps/unwraps them when using @Extra, @FragmentArg, @InstanceState and other Bundle related annotations.
-
ActivityStarter - Supports natively Parceler objects as arguments to Activities, Fragments, Services, etc.
-
Remoter - Supports natively Parceler objects as arguments in @Remoter interfaces.