s-hunter
s-hunter

Reputation: 25816

How to Parcelize a HashMap using Kotlin's Parcelize?

This is what I have for trying @Parcelize a HashMap

@Parcelize
class DataMap : HashMap<String, String>(), Parcelable

But it can't even compile with the following code.

val data = DataMap()
data.put("a", "One")
data.put("b", "Two")
data.put("c", "Three")

val intent = Intent(this, DetailActivity::class.java)
intent.putExtra(DATA_MAP, data)
startActivity(intent)

It complains at this line intent.putExtra(DATA_MAP, data) with error:

Overload resolution ambiguity. All these functions match.

public open fun putExtra(name: String!, value: Parcelable!): Intent! defined in android.content.Intent

public open fun putExtra(name: String!, value: Serializable!): Intent! defined in android.content.Intent

Upvotes: 1

Views: 3404

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170735

First, @Parcelize only cares about primary constructor parameters, not about superclass; since you have none, the code it generates won't write or read anything from a Parcel.

So instead of extending HashMap (which is a bad idea anyway), you should make it a field:

@Parcelize
class DataMap(
    val map: HashMap<String, String> = hashMapOf()
) : Parcelable, MutableMap<String, String> by map

The MutableMap<String, String> by map part makes DataMap implement the interface by delegating all calls, so data.put("a", "One") is the same as data.map.put("a", "One").

It also doesn't implement Serializable so you won't run into the same overload ambiguity.

You can see the list of supported types at https://kotlinlang.org/docs/tutorials/android-plugin.html and it does include HashMap:

collections of all supported types: List (mapped to ArrayList), Set (mapped to LinkedHashSet), Map (mapped to LinkedHashMap);

Also a number of concrete implementations: ArrayList, LinkedList, SortedSet, NavigableSet, HashSet, LinkedHashSet, TreeSet, SortedMap, NavigableMap, HashMap, LinkedHashMap, TreeMap, ConcurrentHashMap;

Upvotes: 5

Related Questions