kotlin,如何将HashMap放入Parcelable

kotlin, how to put HashMap in Parcelable

在实现 Parcelable 的 class 中,它有一个 HashMap 成员。

看到 Parcelable 有 public final void readMap(Map outVal, ClassLoader loader),但找不到使用它的示例。

如果把地图压平,然后write/read一张一张,在构造函数中如何从地块中提取? (从 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)
        }
    }
}

}

我也遇到了同样的问题。对我有用的解决方案是:

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

    }

希望对您有所帮助,祝您好运!

还是希望大家分享一下readMap()的使用方法。

这里是kotlin版的压平地图,供参考

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

使用@Parcelize,只写

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

它内置了对 HashMap(和其他集合类型)的支持。