[Moshi]认识新一代对Kotlin友好的JSON解析框架

为什么是Moshi

切换到kotlin之后,在使用fastJSON时遇到了一些问题,经过网上的查询,要使fastJSON能够正常工作,需要额外添加 kotlin-reflect 依赖,感觉不是很爽。于是一通搜索之后,找到了著名的Square团队的又一个优秀的开源库——Moshi。
它在允许使用传统的反射机制进行JSON序列化与反序列化的同时,也可以通过注解的方式在编译时生成解析类,不必引入2M+的reflect包。
Moshi在使用上没有fastJSON那么直接,但也只是多了一点步骤。
(顺便吐槽一下,fastJSON提供了专门的Android版本,居然是在版本号的最后添加.android后缀来区分,以至于在gradle里面一直被标记为低版本,简直对强迫症患者充满了恶意)

开始使用

官方的文档对于想要快速上手的同学其实并不友好,写得零碎且过于技术。我一向认为,作为工具,首先应该提供给用户的应该是一份Guide,而不是上来就把一堆进阶用法,技术细节,设计哲学甩人脸上。
在接触一个新的工具库的时候,能在学习之中获得反馈,我认为是很重要的。
所以,在这里,就先从最简单的情况入手,开始Moshi的使用之旅。

新建空白工程

在Android Studio中新建一个全新的工程,只包含一个空白的Activity作为学习的环境。再纯粹不过了,没有其他的干扰。(没必要去配置专门的mock测试环境)

添加依赖项

在app模块的build.gradle文件中,配置以下几个部分

plugins {
    // ... 前面自带的内容不去动
    id 'kotlin-kapt'
}

dependencies {
     // ... 前面自带的内容不去动
    implementation 'com.squareup.moshi:moshi:1.11.0'
    kapt "com.squareup.moshi:moshi-kotlin-codegen:1.11.0"   // 使用注解方式需要添加此项
}

kapt {
    correctErrorTypes true
}

点击Sync Now,等待依赖下载。

测试代码的位置

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 在这里插入测试代码,通过Log查看输出
    }
}

好了,准备工作完成。姑且约定在onCreate中插入的代码称其为主代码段

最简单的例子

不要其他花里胡哨的功能,直接从包含单个Object的JSON字符串反序列化出对应的java对象。

新建kotlin文件 Student.kt

@JsonClass(generateAdapter = true)
data class Student(var studentName: String, var studentAge: Number)

主代码段

val JSON_OBJ_STR = """
        {
            studentName: "Lily",
            studentAge: 12
        }
    """
val moshi = Moshi.Builder().build()
val adapter = moshi.adapter(Student::class.java)
val student = adapter.fromJson(JSON_OBJ_STR)
Log.d("Test JSON", student.toString())

以上的代码实际上是有问题的,当你连接上模拟器,兴高采烈地点下绿色的小三角,等待构建、打包、安装、执行。
然后一条异常信息无情地出现在Logcat之中。

Platform class java.lang.Number requires explicit JsonAdapter to be registered

当时我是蒙逼的,google了好一圈,才意识到,只需要把studentAge的类型改为 Int 就可以了。使用Moshi的时候,字段的类型必须准确地指定为 Long,Int之类的,我是最近js写多了,顺手就写了个Number上去,AS也没有报错,结果一开始根本不知道哪里出了问题。

很好,让我们再来一次,绿色小三角走起!
又一个异常。

com.squareup.moshi.JsonEncodingException: Use JsonReader.setLenient(true) to accept malformed JSON at path $.

不要管它给出的修改建议,出现这个异常的原因是,解析器在默认情况下不允许宽松的JSON格式,而我们给出的字符串中,字段名忘了加双引号,所以会报错。
所以,把双引号加上就好。
(要允许宽松格式也很简单,不过我个人认为保证严格准确的格式是有益的,所以这里就不提方法了)

再次运行。很快,我们就在Logcat中看到以下内容

Test JSON: Student(studentName=Lily, studentAge=12)

到这里,最基本的Moshi使用已经没有问题了。

尾巴

在大多数情况下,moshi对象和相应的adapter对象可以封装为全局单例,所以别看写起似乎比fastJson要繁琐,实际上也是非常方便的。

你可能感兴趣的:([Moshi]认识新一代对Kotlin友好的JSON解析框架)