A beginners guide to power-up Bundles and Intents.
While starting out working with Android one of the major issue developers usually have, is passing data between Activities, Fragments, Services, etc. some get around the problem by allocating data in memory or running for what seems to be the most common solution, moving all variables and/or objects to the Application instance 😵.
Note: I’ve written a small article on how to navigate between your Android components that applies this article’s knowledge but takes it a step further. I do recommend to read this first if you are not familiar with Intent/Bundles.
How Do They Do It?
The standard way to pass data in Android is using Intents/Bundles. When you’re sending data between Activities/Receivers/Services means this data will be serialized (converted into a byte array) and deserialized (from byte array) once requested. Note that only certain data types are considered
MARKDOWN_HASHeeeee61162910dd6dbdf06bc0317fa32MARKDOWN_HASH and they are explicitly spelled out in the Bundle API.
In the destination, you will always have Deep copies of your data/objects.
Practice makes perfect 👍
In order to pass your own custom objects, you have to implement either Serializable (please don’t) or Parcelable, if not, the data for each field must be passed individually which translates into a lot of manual work.
The Foo object does not implement the Parcelable interface, there is no way to deserialize or serialize the data. Starting a new Activity while passing the foo’s data:
If Foo has a
MARKDOWN_HASHeeeee61162910dd6dbdf06bc0317fa32MARKDOWN_HASH implementation, archiving the same result is simple
Note: order matters in Parcelable, so be sure to keep it right if you make any manual changes:
plugin-generatedParcelable default implementation
Accessing the passed data is the same as (literally) getting it from a Bundle. The most important aspect is to use the same keys while accessing the data, no matter what your destination component is.
Activities access the Intent’s data by calling getIntent().getExtras(), this will return a bundle with the passed data.
On the other if you are using fragments passing data, create a Bundle and pass it as the fragment’s arguments:
Retrieving this data on the fragment’s instance:
String passedString = getArguments().getString("keySomeValue"));
There are some highly battle tested libraries that make this process easier:
- EventBus: is an open-source library for Android using the publisher/subscriber pattern for loose coupling. EventBus enables central communication to decoupled classes with just a few lines of code — simplifying the code, removing dependencies, and speeding up app development.
- Otto: is an event bus designed to decouple different parts of your application while still allowing them to communicate effectively. Forked from Guava, Otto adds unique functionality to an already refined event bus as well as specializing it to the Android platform.
- RxJava: A quick google search will point you to multiple uses of RxJava as a Bus, which wasn’t exactly designed to be used as it, but works. Although I wouldn’t recommend using RxJavajust for this functionality.
[AndroidBits]: Small articles (bits, get it? 🤓) discussing simple topics, that I found to be of immense value during my quest to become a better dev!