It's been a long time since my last post; I've been busy writing closed source code up until recently when I started writing a library called PaperParcel. PaperParcel is a new annotation processor for automatically generating all of the boilerplate code for making your model objects Parcelable in Android.
Parcelable is the preferred mechanism for passing data to a Bundle (e.g. savedInstanceState) or an Intent (e.g. for passing data to an Activity) because of its speed over Serializable1. The only downside to using Parcelable over Serializable is writing all of the boilerplate code that goes with it, and PaperParcel eliminates this downside.
Now I know, I know, there are already a few similar tools. This post is intended to convince you as to why PaperParcel has an important place in the Android development ecosystem, and to hopefully get some interest in the library so that I can get some more early feedback.
So then, why PaperParcel?
Let's start with the biggest reason: it supports Kotlin data objects! I'm a huge fan of Kotlin, I jumped on the hype train after a paper from Jake Wharton endorsing its use on Android. I wrote my first sample app in Kotlin recently, and discovered that none of the existing Parcelable processors supported Kotlin. I pretty quickly abandoned my project to work on PaperParcel.
When designing the project, I realised that although the goal was to support Kotlin data objects first hand, it would actually be only a small amount of extra effort to make this processor work for Java objects too. Initially I still felt that supporting Java would be unnecessary as there were already so many tools to do this. However, as my development went on and my testing began, I realised several reasons why it was worth it for me to switch my java projects over to PaperParcel too.
OK, for Kotlin it makes sense, but why would I want this in my Java-based app?
Let's start with the reason that I care about the most, compile-time failures if anything is wrong. All of the existing libraries heavily rely on methods in the Parcel class that even the Android docs say you shouldn't use! For example, Parcel#writeMap(Map). Or better yet, the most popular processor auto-parcel only uses Parcel#writeValue(Object) and Parcel#readValue(Object). Just try using these methods with any other type of Map than a HashMap. Your app will compile, but it'll crash with a ClassCastException as soon as unparcelling occurs because Parcel#readValue(Object) will read in a HashMap. PaperParcel never uses readValue/writeValue, and instead favours more efficient and typesafe methods on the Parcel class.
The next reason, which is arguably the biggest feature of PaperParcel, is that it can figure out how to parcel anything! How else would it be able to handle Kotlin data objects? Those aren't parcelable at all, nor are they serializable. The goal is to allow you to write your model objects exactly as you want them, and for PaperParcel to figure out how it can be parcelled. You can feed it an object with all sorts of fields and it'll recursively build up code to write it to a parcel and read it back out. I'll write an article later on about how it works if people are interested, or you can just check out the code.
A more minor detail, but still a nice touch, is that PaperParcel uses the correct methods for parcelling objects. Sometimes Android has hard-to-discover ways of Parcelling objects. Take CharSequence, for example. Ever heard of
TextUtils#writeToParcel(CharSequence, Parcel, int)? I hadn't, until I wrote this library. You could potentially learn some new things from looking at the output from PaperParcel. After all, the project generates Java classes using Square's JavaPoet, and the generated code is really quite nice.
Compelling, but can I use it with AutoValue?
Yes. PaperParcel has an AutoValueExtension for AutoValue users!
implements Parcelable to your
@AutoValue class and all the grunt work is done for you.
AutoValue extensions are still a work-in-progress, but the first version is sampled in the autovalue-example project.
Making your class Parcelable just became less work than making it Serializable!
For speed comparisons for Parcelable vs. Serializable, see http://www.developerphil.com/parcelable-vs-serializable/ ↩