【问题标题】:kotlin, how to put HashMap in Parcelablekotlin,如何将 HashMap 放入 Parcelable
【发布时间】:2018-07-20 20:26:34
【问题描述】:

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

Saw Parcelable 有 public final void readMap(Map outVal, ClassLoader loader),但找不到可以使用的样本。

如果通过展平地图并相应地写入/读取来做到这一点,如何从构造函数中的包裹中提取? (从 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)
        }
    }
}

}

【问题讨论】:

    标签: android kotlin hashmap parcelable


    【解决方案1】:

    使用@Parcelize 并直接写

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

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

    【讨论】:

    • 太棒了!请注意,您需要 plugins {id 'kotlin-parcelize'} 到您的模块 build.gradle 才能使其工作。
    【解决方案2】:

    至于我也面临同样的问题。为我工作的解决方案是:

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

    希望对你有帮助,祝你好运!

    【讨论】:

    • 感谢@Serg!,加上 1 建议不要使用主构造函数语法。有用。希望有其他使用内置final void readMap(Map outVal, ClassLoader loader)的示例
    【解决方案3】:

    仍然希望有人分享如何使用 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)
            }
        }
    }
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-20
      • 1970-01-01
      • 1970-01-01
      • 2012-03-12
      • 2021-08-30
      • 1970-01-01
      • 2015-12-08
      • 2012-01-13
      相关资源
      最近更新 更多