Kotlin中如何解决LinkedTreeMap转ArrayList泛型类型转换问题?
解决LinkedTreeMap转ArrayList的问题
核心思路
在Android API 33+(TIRAMISU)版本中,通过getParcelableArrayList获取的列表元素意外转为LinkedTreeMap,本质是序列化/反序列化过程中对象被解析成了键值对结构。我们可以借助Gson将LinkedTreeMap反向解析为目标Parcelable实体类,同时保留函数的通用性。
解决方案代码
首先确认项目已引入Gson依赖(未引入则添加):
implementation 'com.google.code.gson:gson:2.10.1'
修改扩展函数如下:
@Suppress("DEPRECATION") inline fun <reified T : Parcelable> Bundle.getBaseParcelableArrayList(key: String): ArrayList<T>? { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val rawList = getParcelableArrayList<Parcelable>(key) val targetList = arrayListOf<T>() val gson = Gson() rawList?.forEach { item -> try { // 将LinkedTreeMap转为JSON字符串,再解析为目标实体类 val jsonStr = gson.toJson(item) val targetItem = gson.fromJson(jsonStr, T::class.java) targetList.add(targetItem) } catch (e: Exception) { // 捕获转换异常,避免整体崩溃 e.printStackTrace() } } // 转换后列表为空则返回null,对齐旧版本逻辑 return if (targetList.isNotEmpty()) targetList else null } else { @Suppress("UNCHECKED_CAST") getParcelableArrayList(key) as ArrayList<T>? } }
关键细节说明
- 先以
Parcelable类型获取原始列表,避免提前强转触发类型错误 - 利用Gson完成转换:
LinkedTreeMap的键值对结构和JSON完全匹配,可直接映射到实体类字段 - 增加异常捕获,防止单个元素转换失败导致整个函数异常
- 低版本逻辑保持不变,保证系统兼容性
调用示例
val brandData: ArrayList<Item>? = bundle?.getBaseParcelableArrayList(AppConstantV2.BundleKey.BRAND_SCREEN_DATA)
额外注意事项
- 自定义
Item类的字段名需与LinkedTreeMap中的键名一致,或通过@SerializedName指定映射关系,示例:
@Parcelize data class Item( @SerializedName("brand_name") val brandName: String, val id: Int ) : Parcelable
- 确保
Item类正确实现Parcelable(推荐用@Parcelize简化代码编写)
内容的提问来源于stack exchange,提问作者Ishika Singh
相关产品推荐
相关产品推荐

