Unpacking the Android Bundle with AutoValue Extensions at Uber Engineering
August 16, 2017 / Global
The Android Bundle is a convenient and sometimes necessary object for wrapping data to pass across process boundaries and send with intents, as well as to store state between configuration changes. Unfortunately, wrapping data in a Bundle often requires repetitive and error-prone code. What makes this even worse is that a Bundle attached to an intent from GCM (Google Cloud Messaging) loses type information because GCM serializes the data as String-String key-value pairs.
When investigating a solution for how to eliminate the unbundling of Bundled GCM objects for Uber’s Android rider app, we realized that not only is the data provided generally read-only, but also used to populate data shown on a notification and determine business logic for corresponding pending intents. These objects are prime examples of value classes; classes which are final, immutable, and have implementations of equals, hashCode, and toString based only on the instance’s state.
Generating value classes is simple using AutoValue, which takes an abstract class that defines its fields by its getter method return type and names and then generates a concrete value class that subclasses the interface. AutoValue also provides a framework for extensions by chaining them together. Below, we provide an example of the AutoValue framework for chaining together extensions:
final class AutoValue_BundledObject extends $AutoValue_BundledObject {
// Unbundle implementation
}
final class $AutoValue_BundledObject extends BundledObject {
// AutoValue value type implementation
}
@AutoValue
public abstract class BundledObject {
static BundledObject create(…) {
return new AutoValue_BundledObject(…);
}
// Abstract properties
}
While an AutoValue extension exists to handle the repetitive Parcelable code, there was not one for Bundles. To address this at Uber, we created and open sourced AutoValue: Bundle Extension. In this article, we discuss how our new tool unbundles data and handles type interferences, enabling Android engineers to quickly unbundle data into a value class. This tool decreases the likelihood of encountering bugs and iterative code as well as losing type information, in turn improving the overall app experience for our Android users.