当你还在⽤Gson时,Square那帮⼈已经开发出了Moshi了!!
:
好久不见,曾经我们相处得很好,但是是时候说再见了。
在你的朋友圈中也许会听到这样的语句(也可能没有),但这并⾮是本篇⽂章的主题,我们要谈论的是⼀个新的关于 Android 和 kotlin 序列
化框架!我们需要将 Gson 迁移到 Moshi上⾯了。
当我们谈论为啥Moshi是更优秀的框架,或者怎么迁移到 Moshi之前,我们先来了解⼀下今天的 Gson 的发展。
Gson,what?
当我们查看 Gson 的仓库时,它是这么描述的:
⼀个Java 的序列化/反序列化框架,⽤来将Java对象转换成Json对象,或者反之。
那么它有以下缺点:
很显然它对kotlin并不友好,当然也不是kotlin写的( Gson 是纯Java实现的),所以每个⼈都可以清楚的意识到 Gson 已经不再是⼀个
现代的开发框架了。它发布于2008年,距离今天已经12年了,看上去已经不更新了(这个的确,看了⼀下最新的⼀次更新时间是9个⽉
钱了),完完全全是⼀个将死的项⽬了。
最近没有更新,上⼀次更新看上去并没有⼤的更新或者问题修复(意思就是⼩修⼩补),事实上不去碰那些运⾏得很好的程序,破坏数百
万使⽤Gson库的app 是有道理的(个⼈认为这⾥还是正⾯夸赞了Gson的流⾏和稳定),但是对于Gson这个项⽬来说,它似乎正在死
去。
Gson 库的⽅法数⼤概为1036个,⼤概是 Moshi 库中⽅法数的两倍(Moshi中⽅法数⼤概为500)。
库的体积 使⽤ Gson ⼤约使你的app增⼤了300kb,⽽Moshi⼤概有120kb。
Gson 使⽤了 Java的反射实现了序列化和反序列,⽽ Moshi 使⽤了 Kotlin 代码⾃动⽀持。
Gson不⽀持对象属性有默认值。如果在Gson字符串中缺少了属性对应的字符串,即使你设置了默认值,它将来还是null值(这个不是特
别明⽩啥意思)。
假设我们认为 Gson 将死,那我们将⾛向何⽅?当然我们可以继续使⽤ Gson,因为它⼀直都正常⼯作!但是对于那些好奇⼼很强的开发者
和kotlin爱好者来说,我们还有 Moshi。接下来我们来看看 什么是 Moshi 和 为什么是 Moshi了。
什么是 Moshi ?
⼀个 现代的 kotlin 和 Java Json解析库
(也是⼤名⿍⿍的square公司出品的)。主要特点是 现代的、kotlin友好的、更快的、拥有⼤量可靠的功能。先来看看这些⽜叉的功能吧:
更好的 API
Moshi提供了更好更现代的 API,你可以使⽤此强⼤功能的 API 进⾏简单整洁的操作。
在 Moshi中 注解(Annotation) 被视为最重要的部分,注解可以允许你添加⼀些信息来更加细粒度的实现上下⽂序列化。
你可以⾃定义注解来解析你的Json数据属性,(就像解析颜⾊使⽤@ColorInt, @FromHexColor⼀样)
⾃定义适配器或者上下⽂反序列可以使功能更加整洁,从⽽减少样板代码。
Moshi 拥有更好的、更具⼈性化的获取序列化失败信息的能⼒。在当你的app发布之后,从奇怪的堆栈信息中不知道应该做什么,那么
Moshi将会是⼀个巨⼤的进步(可以帮助你获取异常信息)。
Moshi 拥有 newBuilder() ⽅法从上游的Adapter中来帮助创建新的Adapter,这就有点像OkHttp 或者 Okio builder模式了,它超级
有⽤,因为你可以创建独⽴的Adapter,这样就不需要拥有解析全部对象的Adapter(这句话的意思,需要理解Moshi解析字符流的⽅式
和Gson不⼀致,Gson是从前到后,⼀个字符不落下去解析,⽽Moshi可以直接跳过⽬标字符,只需要得到⾃⼰想要的字符)
Moshi ⽀持多态数据类型,同时也⽀持未知的数据类型的回退。
Moshi在 Kotlin 中拥有代码⾃动⽣成功能,这个很好!在注解的帮助下,你可以更加快速的序列化反序列化.这个⽐Gson使⽤反射⽅
法快多了。
Moshi 的表现
Moshi ⽐ Gson 要快(通过实验得出结论), ⽽且Moshi消耗的内存更少,这是因为它使⽤了 Okio,Okio可以在解析Json字符流的过程提前
预测或者期望忽略掉未知的、不需要的字段(从⽽达到速度快、内存⼩的⽬的, ). Retrofit底层也是⽤了 Okio,所以你才会发⽣什么?
Json序列化库(Moshi) 和 ⽹络请求⼯具(Retrofit) 可以共⽤它们的缓冲区,这样将会在⽹络请求和序列化时降低内存的消耗。
理论说的差不多了,看看代码咋写吧
来看看咋样⼀步⼀步从Gson迁移到 Moshi 吧。
1. 添加 依赖
/*Moshi*/
def moshiVersion = "1.10.0"
implementation(":moshi:$moshiVersion")
kapt(":moshi-kotlin-codegen:$moshiVersion")
implementation("it2:converter-moshi:2.9.0")
2. 将所有的 @SerializedName 替换成 @Json
data class MediaCandidateData(
@SerializedName("width")
val width: Int,
@SerializedName("height")
val height: Int,
@SerializedName("url")
val url: String
)
替换为:
data class MediaCandidateData(
@Json(name = "width")
val width: Int,
@Json(name = "height")
val height: Int,
@Json(name = "url")
val url: String
)
3. 给所有的Data Class 添加 @JsonClass(generateAdapter = true) 注解
给所有的Data Class 添加 @JsonClass(generateAdapter = true)注解,将会参与到序列化反序列化的进程中。它帮助Moshi使⽤代码
⾃动⽣成⽽⾮使⽤将会降低速度的反射。
@JsonClass(generateAdapter = true)
data class MediaCandidateData(
@Json(name = "width")
val width: Int,
@Json(name = "height")
val height: Int,
@Json(name = "url")
val url: String
)
4. 替换Gson的实例为 Moshi
如果使⽤ Dagger 来提供依赖,你可以需要这么⼲:
@Singleton
@Provides
fun provideGson() = GsonBuilder().tLenient().create()
替换为:
@Singleton
@Provides
fun providesMoshi() = Moshi.Builder().build()
5. 使⽤ Retrofit时替换 converter
当你使⽤Retrofit 和 Dagger 时,你可能需要这么做:
@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient, gson: Gson) = Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.baUrl(BASE_ENDPOINT)
.build()
现在替换为:
@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient, mosh: Moshi) = Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(MoshiConverterFactory.create(mosh))
.baUrl(BASE_ENDPOINT)
.build()
就是这么简单,从Gson迁移到 Moshi⾮常简单。
当然也有些特例需要单独讲明,这可能需要下篇⽂章说明了。
本文发布于:2023-05-21 15:22:33,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/1684653754171727.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:当你还在用Gson时,Square那帮人已经开发出了Moshi了!!.doc
本文 PDF 下载地址:当你还在用Gson时,Square那帮人已经开发出了Moshi了!!.pdf
留言与评论(共有 0 条评论) |