Search code examples
androidkotlinhashmapparcelable

kotlin, how to put HashMap in Parcelable


In a class who implements Parcelable it has a HashMap member.

Saw Parcelable has public final void readMap(Map outVal, ClassLoader loader), but could not find a sample to use it.

If do it by flatten the map and write/read one by one accordingly, how to extract from the parcel in the constructor? (got error to build the map from the parcelable, cannot access buildTheMap() before constructor is called)

class CachedData(val type: Int,
             val name: String,
             val details: HashMap<String, String) :
    Parcelable {

constructor(parcel: Parcel) : this(
        parcel.readInt(),
        parcel.readString(),

        // how to get the hashMap out of the parcel???
        buildTheMap(parcel)   //<=== cannot access buildTheMap() before constructor is called
)

fun buildTheMap(parcel: Parcel) :HashMap<String, String> {

    val size = parcel.readInt()
    val map = HashMap<String, String>()

    for (i in 1..size) {
        val key = parcel.readString()
        val value = parcel.readString()
        map[key] = value
    }
    return map
}

override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeInt(type)
    parcel.writeString(name)

    // how to write the HashMap<String, String> to the parcel
    //parcel.???

    parcel.writeInt(details.size)
    for ((key, value) in details) {
        parcel.writeString(key)
        parcel.writeString(value)
    }
}

override fun describeContents(): Int {
    return 0
}

companion object {
    @JvmField val CREATOR: Parcelable.Creator<CachedData> = object : Parcelable.Creator<CachedData>{
        override fun createFromParcel(parcel: Parcel): CachedData {
            return CachedData(parcel)
        }

        override fun newArray(size: Int): Array<CachedData?> {
            return arrayOfNulls(size)
        }
    }
}

}


Solution

  • As for me a faced with the same problem. The working for me solution was:

    public class JoustBattler extends Parcelable {
    
    ...
    
     private Map<String, Integer> battleWins;
    
    
     protected JoustBattler(Parcel in) {
            super(in);
    
            int battleWinsSize = in.readInt();
            this.battleWins = new HashMap<String, Integer>(battleWinsSize);
            for (int i = 0; i < battleWinsSize; i++) {
                String key = in.readString();
                Integer value = (Integer) in.readValue(Integer.class.getClassLoader());
                this.battleWins.put(key, value);
            }
    
        }
    
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
    
            dest.writeInt(this.battleWins.size());
            for (Map.Entry<String, Integer> entry : this.battleWins.entrySet()) {
                dest.writeString(entry.getKey());
                dest.writeValue(entry.getValue());
            }
    
        }
    

    Hope it helps, good luck!