Passing HashTables Between Activities

Atanu Dasgupta
3 min readJul 13, 2019

--

When dealing with Android SDK, we come across situations where we need to pass data structures between activities. A simple example would be; we have to login to an application so we need to enter a login id or email for the next activity( say the list of products to choose from). This action allows us to use the user context uniform across two different activities.

First, we create an Intent object, which is used in startActivity. The current activity can pass data( parameters) using a putExtra() method. This works beautifully for most of the data types that we commonly use. The OS parcels the underlying Bundle of the intent. Then, the OS creates the new activity, un-parcels the data, and passes the intent to the new activity using default writeToParcel() method. Here is a simple example of starting another activity by sending the user name to the bundle:-

private void nextPage() {
Intent launchProductPage = new Intent(this, ProductPage.class);
launchProductPage.putExtra("user", username.getText().toString());
startActivity(launchProductPage);
}

You can now move on to the next activity ( say, ProductPage, in this example) and get the data that was sent in the default parcel.

Intent i= getIntent();
logn= i.getStringExtra("user");

The put** and get** methods of the Intent has many signatures for sending and receiving different datatypes which makes it quite flexible for all common dataTypes.

In some cases, where we are sending an object or complex data types, we need to override the writeToParcel() methods to write the data to the parcel correctly.

Here is a code that I implemented for in my application which is sending an object which contains the cart order.

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(description);
dest.writeDouble(rate);
dest.writeDouble(quantity);
dest.writeString(quantityStr);
dest.writeString(rateStr);
dest.writeInt(selectedQuantity);
}

You will also need to create a parcelable creator as follows:-

public static final Parcelable.Creator<product> CREATOR = new Parcelable.Creator<product>() {    public product createFromParcel(Parcel in) {
return new product(in);
}
public product[] newArray(int size) {
return new product[size];
}
};

Now, this code works consistently. The challenge comes when we try passing a complex data structure like HashTable across activities.

HashTable, unlike HashMap, is synchronized in Java, so I prefer using it.

If you use the Intent put* and get* methods on HashTable it will NOT fetch you the data correctly. Part of the reason is the way the OS tries to parse a HashTable does not work properly with bundles.

So, I developed a workaround for it, which was quite useful and it works, I felt sharing this would come handy.

private void viewCartPage(Hashtable<String,product> products) {
Intent launchViewCart = new Intent(this, ViewCart.class);
Collection<product> product_collection_values= new HashSet<product> (products.values());
Collection<String> product_collection_keys= new HashSet<String> (products.keySet());
ArrayList<product> product_array_values = new ArrayList<product>(product_collection_values) ;
ArrayList<String> product_array_keys = new ArrayList<String>(product_collection_keys) ;
launchViewCart.putExtra("com.emerald.milkman.cart.values",product_array_values); launchViewCart.putExtra("com.emerald.milkman.cart.keys",product_array_keys);

HashTable, as you would know, maintains a key-value pair and can retrieve data based on the key, it does not allow duplicates. It is quite useful for some applications. Here, in the above example, HashTable of products keeps all the products selected by the user in the cart. I needed to pass this to the next activity, ViewCart so that I can show the products in a ListView.

So, here first I am transposing the Hashtable, values, and keys in two Collections of keys and values. After that, I create ArrayLists for both keys and values and then pass it to bundle. This works well, without any complications.

In the next activity(ViewCart) I can retrieve them as follows.

Bundle bundle = getIntent().getExtras();
ArrayList<product>allProducts_values ;
allProducts_values =(ArrayList<product>) getIntent().getSerializableExtra(
"com.emerald.milkman.cart.values");
ArrayList<String> allProducts_keys= bundle.getStringArrayList("com.emerald.milkman.cart.keys");

Now in ViewCart, we can recreate the HashTable from the two ArrayList easily, which gives me the original HashTable of products to work on in ViewActivity.

for (int i=0;i<allProducts_keys.size();i++)
allProducts.put(allProducts_keys.get(i), allProducts_values.get(i));

Serializing and deserializing objects is another way, however, it could possibly have performance issues for your application.

I hope you enjoyed reading this, I’d appreciate your comments and questions if any.

Here are other Articles I have written for your references.

Creating a horizontal scrolling calendar using Android SDK

--

--

Atanu Dasgupta
Atanu Dasgupta

Written by Atanu Dasgupta

technology enthusiast with passion for learning

No responses yet