Android Kotlin中获取HashMap值遇类型转换异常,求解决方案
问题原因
你用Gson序列化MutableMap<String, StorageData>存入SharedPreferences时,Gson默认不会保留泛型类型信息,取出时会把Map中的值解析成LinkedTreeMap(Gson内置的Map实现类),而非你定义的StorageData实体类,直接强转就会触发ClassCastException。
解决方法
方案1:用TypeToken指定泛型类型解析
从SharedPreferences读取数据时,通过TypeToken明确告知Gson目标泛型类型,避免自动解析成LinkedTreeMap:
// 读取存储信息的代码改造 val gson = Gson() val storageJson = appPreference.getString("storage_info_key", "") ?: "" // 用TypeToken明确泛型类型 val targetType = object : TypeToken<MutableMap<String, StorageData>>() {}.type val storageMap: MutableMap<String, StorageData> = gson.fromJson(storageJson, targetType) // 后续取值无需强转 if (storageMap.isNotEmpty() && storageMap.containsKey(modelNumber)) { containerView.apply { val storageData = storageMap[modelNumber] tv_total.text = storageData?.total tv_free.text = storageData?.free tv_movie.text = storageData?.movie tv_event.text = storageData?.event } }
方案2:封装成含Map的实体类
定义一个包裹Map的实体类,让Gson能准确识别嵌套类型,避免泛型丢失:
// 定义包裹类 data class StorageWrapper(val storageMap: MutableMap<String, StorageData>)
存入时序列化这个包裹类:
val wrapper = StorageWrapper(yourOriginalStorageMap) val json = gson.toJson(wrapper) appPreference.edit().putString("storage_info_key", json).apply()
取出时直接解析成包裹类:
val json = appPreference.getString("storage_info_key", "") ?: "" val wrapper = gson.fromJson(json, StorageWrapper::class.java) val storageMap = wrapper.storageMap
方案3:手动转换LinkedTreeMap到StorageData
如果无法修改原有存储逻辑,可手动将LinkedTreeMap的键值对映射到StorageData实体:
if (appPreference.getStorageInfo().isNotEmpty() && appPreference.getStorageInfo().containsKey(modelNumber)) { val linkedHashMap = appPreference.getStorageInfo() val treeMap = linkedHashMap[modelNumber] as LinkedTreeMap<*, *> // 手动映射属性,确保key与StorageData属性名一致 val storageData = StorageData( total = treeMap["total"] as? String, free = treeMap["free"] as? String, movie = treeMap["movie"] as? String, event = treeMap["event"] as? String ) containerView.apply { tv_total.text = storageData.total tv_free.text = storageData.free tv_movie.text = storageData.movie tv_event.text = storageData.event } }
注意:此方案依赖LinkedTreeMap的key与StorageData属性名完全匹配,且类型兼容,否则会出现空值或转换异常。
内容的提问来源于stack exchange,提问作者MARSH
相关产品推荐
相关产品推荐

