JSON Moshi库

你已经了解了将数据序列化为 JSON 格式进行传输的好处。手动转换类并不方便,不过幸运的是,有许多库能简化这个过程。在 Android 开发中,一个非常流行且常用的库叫做 Moshi。

Moshi 的 API 比其他知名库(如 Jackson 和 Gson)要小很多。Gson 有超过一千个方法,而 Moshi 只有一半。Moshi 体积也更小,只有 100KB 多,而 Gson 约为 300KB。

Moshi 速度快,占用内存少,是一个很好的选择。在本节中,你将学习如何使用它,同时进一步了解 JSON 的结构。

添加库依赖

要使用 Moshi 库,需要在 build.gradle.kts 文件的 dependencies 部分添加如下依赖:

implementation("com.squareup.moshi:moshi-kotlin:1.11.0")

代码说明
添加这行后,IDE 会在你编写代码时自动导入需要的类。

你可以访问 Moshi 的 GitHub 页面了解更多信息。


将 Kotlin 对象序列化为 JSON 字符串

首先定义一个 Human 类,用于演示操作:

class Human(var name: String, var age: Int, var friends: Array<String>)

代码说明
这是一个简单的类,包含姓名、年龄和朋友数组。

接下来创建 Human 类的实例:

val human = Human("Mike", 20, arrayOf("Alex", "Valery", "Ann"))

代码说明
创建了一个名为 Mike、20 岁,有三个朋友的对象。

使用 Moshi 需要通过 Builder 模式创建一个 Moshi 实例:

val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

代码说明
这是 Moshi 的标准构造方式,KotlinJsonAdapterFactory() 用来支持 Kotlin 的特性。

接着,需要为 Human 类创建一个适配器,用于序列化和反序列化:

val humanAdapter = moshi.adapter(Human::class.java)

代码说明
Human::class.java 是 Kotlin 中获取类的 Java 反射对象的方式。

这样,我们就可以快速地将对象转换成 JSON 字符串了,比如:

print(humanAdapter.toJson(human))
// 输出: {"name":"Mike","age":20,"friends":["Alex","Valery","Ann"]}

代码说明
toJson() 方法把 human 对象转换成 JSON 格式的字符串。


将 JSON 反序列化为 Kotlin 对象

有了适配器后,我们可以用它来根据 JSON 字符串重新创建对象:

val newHumanString = """
    {"name":"John",
    "age":25, 
    "friends":["Mike","Helen"]}""".trimIndent()

val newHuman = humanAdapter.fromJson(newHumanString)

代码说明
fromJson 方法把 JSON 字符串转成 Human? 对象(注意是可空类型),因为解析可能失败,返回 null。


反序列化更复杂的数据结构 — 对象列表

如果要处理两个类的组合,比如 HumanList,需要使用 ParameterizedType

val humanList = listOf(human, newHuman)

val type = Types.newParameterizedType(List::class.java, Human::class.java)
val humanListAdapter = moshi.adapter<List<Human?>>(type)
print(humanListAdapter.toJson(humanList))
// 输出: [{"name":"Mike","age":20,"friends":["Alex","Valery","Ann"]},{"name":"John","age":25,"friends":["Mike","Helen"]}]

代码说明
通过 Types.newParameterizedTypeListHuman 组合起来创建适配器,方便处理列表。

也可以用它反序列化 JSON 字符串:

val jsonStr =
    """[{"name":"Nick","age":10,"friends":["Valery"]},
       {"name":"John","age":25,"friends":[]},
       {"name":"Kate","age":40,"friends":[]}]
       """.trimIndent()

val newHumanList = humanListAdapter.fromJson(jsonStr)

操作反序列化后的 JSON 对象

反序列化后,可以轻松访问对象的属性:

print(newHuman?.name) // 输出: John

访问更复杂的数据:

print(newHuman?.friends.contentToString()) // 输出: [Mike, Helen]

遍历列表中所有对象:

for (h in newHumanList!!) {
    print(h?.name + " ")
}
// 输出: Nick John Kate

这里我们用 !! 断言列表不为空。


增加 Map 类型字段

修改 Human 类,加入显示科目成绩的 Map

class Human(var name: String, var age: Int, var friends: Array<String>, var grades: Map<String, String>)

创建对应包含 Map 的适配器:

val type = Types.newParameterizedType(List::class.java, Human::class.java, Map::class.java)
val humanListAdapter = moshi.adapter<List<Human?>>(type)

然后像之前一样用 JSON 字符串反序列化:

val jsonStr =
    """[{"name":"Ruslan","age":20,"friends":["Victoria","Valery"],
        "grades":{"Math":"A","Philosophy":"F","Physics":"D"}},
        {"name":"Victoria","age":35,"friends":["Ruslan","Anastasia"],
        "grades":{"Math":"B","Philosophy":"C","Physics":"B"}}]""".trimIndent()
val humanList = humanListAdapter.fromJson(jsonStr)

最后输出某人某科成绩:

for (h in humanList!!) {
    println(h?.name + " has a grade of ${h!!.grades["Math"]} in maths")
}
// 输出:
// Ruslan has a grade of A in maths
// Victoria has a grade of B in maths

总结

本节你学习了 Moshi 库的优点,了解了如何利用它将 Kotlin 对象转成 JSON 字符串,及如何从 JSON 字符串反序列化回对象或对象列表,并且演示了如何操作反序列化得到的对象数据,同时加深了对 JSON 结构的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值