问题
I have a MutableMap<CryptoTypes, CurrentTradingInfo>
that I'm wanting to save in onSaveInstanceState
and was going to use Moshi to convert back and forth. CryptoTypes is an ENUM
private var tickerData: MutableMap<CryptoTypes, CurrentTradingInfo> = mutableMapOf()
fun convertTickerDataJson(): String {
val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter<MutableMap<CryptoTypes, CurrentTradingInfo>>(MutableMap::class.java)
return jsonAdapter.toJson(tickerData)
}
fun restoreTickerDataFromJson(data: String) {
val moshi = Moshi.Builder().build()
val jsonAdapter = moshi.adapter<MutableMap<CryptoTypes, CurrentTradingInfo>>(MutableMap::class.java)
tickerData = jsonAdapter.fromJson(data)
}
The data is serializing correctly, but when it's deserialized, it's giving me back a MutableMap<String, CurrentTradingInfo>
instead?
When I look at my tickerData map in studio before I serialize it, it's clearly storing the ENUM as an ENUM
This is the map after being deserialized back [note the map is unordered and I had to re-run it again, hence the map keys in different orders]
How is it able to give me back an incorrectly typed map? Am I doing something wrong?
When I try to access the map post conversion it crashes with the below since the type is wrong
Java.lang.ClassCastException: java.lang.String cannot be cast to com.nebulights.crytpotracker.CryptoTypes
If I create two variables
private var tickerDataA: MutableMap<CryptoTypes, CurrentTradingInfo> = mutableMapOf()
private var tickerDataB: MutableMap<String, CurrentTradingInfo> = mutableMapOf()
I can't go tickerDataA = tickerDataB
, it shows as a type mismatch and won't let me compile as it should.
回答1:
moshi.adapter<MutableMap<CryptoTypes, CurrentTradingInfo>>(MutableMap::class.java)
The problem occurs because you are not providing the complete type, only the generic MutableMap
class. Because of this it uses the Object
serializer instead of one specialized for the key/value types.
Try creating a parameterized type:
val type = Types.newParameterizedType(MutableMap::class.java, CryptoTypes::class.java, CurrentTradingInfo::class.java)
val jsonAdapter = moshi.adapter<MutableMap<CryptoTypes, CurrentTradingInfo>>(type)
This should provide Moshi with the information it required to correctly serialize the map.
来源:https://stackoverflow.com/questions/47114344/moshi-in-android-kotlin-enum-as-mutablemap-key-being-converted-to-string-when