kotlin, how to put HashMap in Parcelable

一笑奈何 提交于 2020-02-28 19:01:21

问题


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)
        }
    }
}

}


回答1:


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!




回答2:


Still hope some to share how to use the readMap().

Here is the kotlin version to flatten the map, for reference.

class CachedData :
    Parcelable {

var type: Int = 0
var name: String = ""
var details: HashMap<String, String> = HashMap()

constructor (type: Int,
             name: String,
             details: HashMap<String, String>) {
    this.type = type
    this.name = name
    this.details = details
}

constructor(parcel: Parcel) {
    this.type = parcel.readInt()
    this.name = parcel.readString()
    this.details = buildTheMap(parcel)
}

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

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

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

fun writeToMap(parcel: Parcel) {
    parcel.writeInt(details.size)
    for ((key, value) in details) {
        parcel.writeString(key)
        parcel.writeString(value)
    }
}

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

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)
        }
    }
}
} 



回答3:


Use @Parcelize and just write

@Parcelize
class CachedData(val type: Int, val name: String, val details: HashMap<String, String>) : Parcelable

It has built-in support for HashMap (and other collection types).



来源:https://stackoverflow.com/questions/51449891/kotlin-how-to-put-hashmap-in-parcelable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!