首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Moshi三宗罪

  • 25-04-18 08:00
  • 2279
  • 8268
juejin.cn

Android一直使用的是Goolge的Gson,开始使用kotlin后发现Gson处理kotlin的data class会出现各种空指针,kotlin的非空校验失效;于是开始研究Moshi并使用它。 下面我会简单介绍下moshi的使用,并详细说明从Gson转到Moshi存在的我满意的地方。

使用介绍

Json解析有两种方式,一种是给Bean加注解,一种是使用kotlin的反射,为了简单我这里使用的是反射

  • 添加依赖
kotlin
代码解读
复制代码
implementation("com.squareup.moshi:moshi-kotlin:1.15.2")
  • 使用
kotlin
代码解读
复制代码
var moshi = Moshi.Builder() //Date-long转换 .add(DateJsonAdapter()) //moshi官方对kotlin类的处理 .addLast(KotlinJsonAdapterFactory()) .build() fun fromJson(json: String?, type: Type): T? { if (json.isNullOrBlank()) return null return moshi.adapter(type).fromJson(json) }

本人不满意的点

一、强制非空判断

json为null但字段非null时,报异常,但我希望的是如果为null则给个默认值,下面的例子中默认指定了val age: Int = 3,而json里是"age":null,解析结果是异常Expected an int but was NULL at path $.age

kotlin
代码解读
复制代码
private fun testDataClass() { val json = """{"name":"wzw","age":null, "gender":1, "son":{}}""" //com.squareup.moshi.JsonDataException: Expected an int but was NULL at path $.age val fromBeanJson = MoshiUtil.fromBeanJson(json) println("moshi: $fromBeanJson") } data class DataWen( val name: String? = null, //如果为null则使用默认值,但moshi做不到 val age: Int = 3, val gender: Int? = null )

二、无法指定默认值

json为null但字段可null且有默认值,默认值失效,下面的例子中val age: Int? = 3 age可空且指定里默认值,但由于json里的age=null所以最终解析出来的age=null;这个问题和上面第一个问题类似,我希望的是null的时候能使用默认值,但是moshi做不到。

kotlin
代码解读
复制代码
private fun testDataClass() { val json = """{"name":"wzw","age":null, "gender":1, "son":{}}""" val fromBeanJson = MoshiUtil.fromBeanJson(json) //DataWen(name=wzw, age=null, gender=1) println("moshi: $fromBeanJson") } data class DataWen( val name: String? = null, val age: Int? = 3, val gender: Int? = null )

为什么我一定要纠结这个默认值?

因为:

  1. Gson支持默认值,当为null时可以使用默认值,达到对象不为null的效果;
  2. App无法保证后台接口返回的json一定是自己想要的,必须要有容错否则崩溃了就是移动端开发人员的锅;而Moshi的容错能力太差了

三、后台没返回该字段时报错

json没有该字段,但bean中定义了该字段非空,则报错Required value 'age' missing at $。 如下面的例子中,json里没有age字段,但DataWen里定义了非null的age:val age: Int,Moshi在解析时就会报错。

当然,要解决这个问题很简单,只要age给个默认值就可以,如val age: Int = 18。把这个问题列出来是想说Moshi有这个问题,使用时要注意!

kotlin
代码解读
复制代码
private fun 测试dataClass() { val json = """{"name":"wzw", "gender":1, "son":{}}""" //com.squareup.moshi.JsonDataException: Required value 'age' missing at $ val fromBeanJson = MoshiUtil.fromBeanJson(json) println("moshi: $fromBeanJson") } data class DataWen( val name: String? = null, val age: Int, val gender: Int? = null )

四、繁琐或耗时等

Moshi的解析方式有两种,一种是通过注解,需要在每个类上加注解,听说解析速度比Gson快;另一种是通过反射,速度比Gson慢,尤其是第一次解析,甚至比Gson慢十几倍,而且反射需要引入kotlin的反射库,jar包2.5M左右;

  • 注解解析需要
kotlin
代码解读
复制代码
//需要加注解 @JsonClass(generateAdapter = true) data class DataWen( val name: String? = null, val age: Int = 3, val gender: Int? = null )
  • 反射解析初次速度慢

这里一直强调初次/第一次是因为kotlin反射sdk第一次使用有一个初始化过程,这个过程耗时,但是即使第二次第三次使用,moshi的解析也不会比gson快,因为kotlin反射本来就比java的慢;---不只是理解的对不对😄

ini
代码解读
复制代码
//耗时 gson: DataWen(name=wzw, age=null, gender=1) take time: 23 moshi: DataWen(name=wzw, age=null, gender=1) take time: 301

总结

  • Moshi的容错能力不行,App如果要使用moshi,必须要注意上面这些问题,也可以自己写Adapter规避上面这些问题,但这个会影响性能;

  • 如果决定继续使用Gson,则不能使用kotlin的数据类data class,要改为普通的class,且要有默认空构造,且字段不能是val

kotlin
代码解读
复制代码
data class DataWen( val name: String? = null, val age: Int, val gender: Int? = null ) //改为 class DataWen( var name: String? = null, var age: Int, var gender: Int? = null )
  • 以上列出的所有问题通过自定义Adapter都可以解决,就看你愿不愿意折腾;

要解决可参考:github上的moshi-nullsafe

注:本文转载自juejin.cn的麋鹿原的文章"https://juejin.cn/post/7490846852619796495"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

140
Android
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top