Android:Passing a hash map between Activities

The best way to do this is if you can express your data in the primitives supported by Bundle, so it can be placed in the Intent you are sending through the Intent.putExtra() methods. (EXCEPT for the use of Serializable, which is extremely slow and inefficient.)

However you can’t do this because (a) you are using a Map and (b) your map contains a custom data type.

The formally correct solution to this exact problem is to write a custom Parcellable class that takes care of marshalling/unmarshalling your data structure. I’ll sketch out the code here, though it may not be exactly correct:

import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;

public class MyData implements Parcelable {
    HashMap<String, data> data_map = new HashMap<String, data>();

    public MyData() {
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int parcelableFlags) {
        final int N = data_map.size();
        dest.writeInt(N);
        if (N > 0) {
            for (Map.Entry<String, data> entry : data_map.entrySet()) {
                dest.writeString(entry.getKey());
                data dat = entry.getValue();
                dest.writeString(dat.name);
                dest.writeFloat(dat.value);
                // etc...
            }
        }
    }

    public static final Creator<MyData> CREATOR = new Creator<MyData>() {
        public MyData createFromParcel(Parcel source) {
            return new MyData(source);
        }
        public MyData[] newArray(int size) {
            return new MyData[size];
        }
    };

    private MyData(Parcel source) {
        final int N = source.readInt();
        for (int i=0; i<N; i++) {
            String key = source.readString();
            data dat = new data();
            dat.name = source.readString();
            dat.value = source.readFloat();
            // etc...
            data_map.put(key, dat);
        }
    }
}

Note that when you have a custom data structure like your “data” class, it can be cleaner to also make that Parcellable, so it knows how to read/write its contents in a Parcel, and the code here would just call .writeToParcel(…) and a .readFromParcel(…) method on it instead of knowing the details of its contents. That way when you add new fields to “data” you don’t forget to also update this other marshalling code to know about them.

Leave a Comment