如何在Android平台使用Kotlin解析该类型的JSON响应
在Android中用Kotlin解析动态键的JSON响应
嘿,我来帮你搞定这个JSON解析的问题!你的JSON结构有点特别——顶层是动态的门店编码(比如ART01、BHW01),每个编码对应一个门店信息对象。下面我给你两种Android开发中常用的解析方案,都是用Kotlin实现的:
方案一:使用Gson(Google出品的流行解析库)
Gson是很多Android开发者的首选,上手简单,兼容性好。
步骤1:添加依赖
在你的Module级别的build.gradle(或build.gradle.kts)中添加Gson依赖:
dependencies { implementation 'com.google.code.gson:gson:2.10.1' }
步骤2:定义对应的数据类
根据JSON的嵌套结构,我们需要定义两个数据类来映射门店信息和详情:
data class OutletInfo( val outletType: String, val outletDetails: List<OutletDetail> ) data class OutletDetail( val outletName: String, val serverIP: String, val outletKey: String )
提示:如果JSON中可能存在缺失的字段,可以给字段设置默认值,比如
val outletType: String = "",避免解析失败。
步骤3:执行解析
因为顶层是动态键值对,我们直接解析成Map<String, OutletInfo>类型:
// 你的JSON字符串(实际开发中可能来自网络请求或本地文件) val jsonResponse = """{"ART01": {"outletType": "single", "outletDetails": [{"outletName": "ARTISANAL BAKEHOUSE", "serverIP": "150.129.182.214:81", "outletKey": "DESKTOP-N8Q4C2M"}]}, "BHW01": {"outletType": "single", "outletDetails": [{"outletName": "Bhawan", "serverIP": "43.228.143.194:81", "outletKey": "E1"}]}}""" val gson = Gson() // 使用TypeToken来指定泛型类型,Gson需要这个来正确解析Map val outletMap: Map<String, OutletInfo> = gson.fromJson( jsonResponse, object : TypeToken<Map<String, OutletInfo>>() {}.type ) // 遍历解析后的Map,使用数据 outletMap.forEach { (outletCode, info) -> println("门店编码: $outletCode") println("门店类型: ${info.outletType}") info.outletDetails.forEach { detail -> println("门店名称: ${detail.outletName}") println("服务器地址: ${detail.serverIP}") println("门店密钥: ${detail.outletKey}") } }
方案二:使用Kotlin官方的kotlinx.serialization
这是Kotlin官方推荐的序列化/反序列化库,更贴合Kotlin的语法特性,支持空安全和编译时检查。
步骤1:添加依赖和配置
首先在项目根目录的build.gradle中添加插件仓库:
buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-serialization:1.9.20" } }
然后在Module级别的build.gradle中启用插件并添加依赖:
plugins { id 'kotlinx-serialization' } dependencies { implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0" }
步骤2:定义带注解的数据类
给数据类添加@Serializable注解,让库能识别它们:
import kotlinx.serialization.Serializable @Serializable data class OutletInfo( val outletType: String, val outletDetails: List<OutletDetail> ) @Serializable data class OutletDetail( val outletName: String, val serverIP: String, val outletKey: String )
步骤3:执行解析
用Json.decodeFromString直接解析成Map<String, OutletInfo>,无需额外的TypeToken:
import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json val jsonResponse = """{"ART01": {"outletType": "single", "outletDetails": [{"outletName": "ARTISANAL BAKEHOUSE", "serverIP": "150.129.182.214:81", "outletKey": "DESKTOP-N8Q4C2M"}]}, "BHW01": {"outletType": "single", "outletDetails": [{"outletName": "Bhawan", "serverIP": "43.228.143.194:81", "outletKey": "E1"}]}}""" val outletMap: Map<String, OutletInfo> = Json.decodeFromString(jsonResponse) // 使用数据的方式和Gson方案完全一致 outletMap.forEach { (code, info) -> println("编码: $code") println("类型: ${info.outletType}") info.outletDetails.forEach { println("名称: ${it.outletName}, IP: ${it.serverIP}") } }
注意事项
- 实际开发中,如果JSON来自网络请求,一定要在后台线程(比如用Coroutines、RxJava)执行解析,避免阻塞主线程导致ANR。
- 如果JSON结构可能有变化,建议添加字段默认值或者使用
null类型(比如val outletType: String? = null)来提高解析的容错性。
内容的提问来源于stack exchange,提问作者Nitish tiwary
相关产品推荐
相关产品推荐

