问题
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