android 中的 Moshi vs Gson
Moshi vs Gson in android
我正在决定是使用 Moshi by square 还是 Gson 来序列化和反序列化模型数据。
我一直不喜欢 Gson 的一件事是我认为它使用反射,这在 android 上可能很慢? Moshi 也使用反射吗?
moshi 与 Gson 的优缺点是什么?
我认为它们很相似。以创建 typeAdapter:
的语句为例
class CardAdapter {
@ToJson String toJson(Card card) {
return card.rank + card.suit.name().substring(0, 1);
}
@FromJson Card fromJson(String card) {
if (card.length() != 2) throw new JsonDataException("Unknown card: " + card);
char rank = card.charAt(0);
switch (card.charAt(1)) {
case 'C': return new Card(rank, Suit.CLUBS);
case 'D': return new Card(rank, Suit.DIAMONDS);
case 'H': return new Card(rank, Suit.HEARTS);
case 'S': return new Card(rank, Suit.SPADES);
default: throw new JsonDataException("unknown suit: " + card);
}
}
}
并像在 gson 中一样注册它:
Moshi moshi = new Moshi.Builder()
.add(new CardAdapter())
.build();
我想优点是在 typeAdapter 中使用了注解。如果我切换到 Moshi,我想知道是否有任何性能提升。
Moshi 使用 Okio 优化了一些 Gson 没有的东西。
- 当 reading field names 时,Moshi 无需分配字符串或进行哈希查找。
- Moshi 将输入扫描为 UTF-8 字节序列,并延迟转换为 Java 字符。例如,它永远不需要将整数文字转换为字符。
如果您已经在使用 Okio 流,那么这些优化的好处尤其明显。 Retrofit and OkHttp 的用户特别受益于 Moshi。
关于 Moshi 起源的进一步讨论在我的 post、Moshi, another JSON Processor。
根据swankjesse's comment on reddit:
我为自己在 Gson 上的工作感到自豪,但也对它的一些局限性感到失望。我想解决这些问题,但不是作为“Gson 3.0”,部分原因是我不再在 Google 工作。
Jake、Scott、Eric 和我创建了 Moshi 来解决 Gson 的各种限制。以下是选择 Moshi 而不是 Gson 的十个小理由:
即将推出 Kotlin 支持。
像@HexColor int 这样的限定符允许单个Java 类型的多个JSON 表示。
@ToJson 和@FromJson 可以轻松编写和测试自定义 JSON 适配器。
JsonAdapter.failOnUnknown() 让您拒绝意外的 JSON 数据。
可预测的异常。 Moshi 在 IO 问题上抛出 IOException,在类型不匹配上抛出 JsonDataException。 Gson无处不在。
JsonReader.selectName() 避免了常见情况下不必要的 UTF-8 解码和字符串分配。
您将发布一个较小的 APK。 Gson 是 227 KiB,Moshi+Okio 加起来是 200 KiB。
Moshi 不会将平台类型的实现细节泄露到您编码的 JSON 中。这让我害怕 Gson:gson.toJson(SimpleTimeZone.getTimeZone("GMT"))
Moshi 默认不会进行奇怪的 HTML 转义。看Gson默认编码“12 & 5 = 4”为例
默认情况下未安装损坏的日期适配器。
如果您要编写新代码,我强烈建议您从 Moshi 开始。如果你有一个现有的 Gson 项目,你应该升级,如果这既简单又没有风险的话。否则坚持使用 Gson!我正在尽最大努力确保它保持兼容和可靠。
从之前的link可以看出,使用 moshi codegen 将创建编译时适配器来建模 classes,这将删除运行时反射的使用
型号
@JsonClass(generateAdapter = true)
class MyModel(val blah: Blah, val blah2: Blah)
app/build.gradle
kapt "com.squareup.moshi:moshi-kotlin-codegen:$version_moshi"
将生成带有验证的 MyModelJsonAdapter class 以确保模型属性的可空性。
我正在决定是使用 Moshi by square 还是 Gson 来序列化和反序列化模型数据。
我一直不喜欢 Gson 的一件事是我认为它使用反射,这在 android 上可能很慢? Moshi 也使用反射吗?
moshi 与 Gson 的优缺点是什么?
我认为它们很相似。以创建 typeAdapter:
class CardAdapter {
@ToJson String toJson(Card card) {
return card.rank + card.suit.name().substring(0, 1);
}
@FromJson Card fromJson(String card) {
if (card.length() != 2) throw new JsonDataException("Unknown card: " + card);
char rank = card.charAt(0);
switch (card.charAt(1)) {
case 'C': return new Card(rank, Suit.CLUBS);
case 'D': return new Card(rank, Suit.DIAMONDS);
case 'H': return new Card(rank, Suit.HEARTS);
case 'S': return new Card(rank, Suit.SPADES);
default: throw new JsonDataException("unknown suit: " + card);
}
}
}
并像在 gson 中一样注册它:
Moshi moshi = new Moshi.Builder()
.add(new CardAdapter())
.build();
我想优点是在 typeAdapter 中使用了注解。如果我切换到 Moshi,我想知道是否有任何性能提升。
Moshi 使用 Okio 优化了一些 Gson 没有的东西。
- 当 reading field names 时,Moshi 无需分配字符串或进行哈希查找。
- Moshi 将输入扫描为 UTF-8 字节序列,并延迟转换为 Java 字符。例如,它永远不需要将整数文字转换为字符。
如果您已经在使用 Okio 流,那么这些优化的好处尤其明显。 Retrofit and OkHttp 的用户特别受益于 Moshi。
关于 Moshi 起源的进一步讨论在我的 post、Moshi, another JSON Processor。
根据swankjesse's comment on reddit:
我为自己在 Gson 上的工作感到自豪,但也对它的一些局限性感到失望。我想解决这些问题,但不是作为“Gson 3.0”,部分原因是我不再在 Google 工作。 Jake、Scott、Eric 和我创建了 Moshi 来解决 Gson 的各种限制。以下是选择 Moshi 而不是 Gson 的十个小理由:
即将推出 Kotlin 支持。
像@HexColor int 这样的限定符允许单个Java 类型的多个JSON 表示。
@ToJson 和@FromJson 可以轻松编写和测试自定义 JSON 适配器。
JsonAdapter.failOnUnknown() 让您拒绝意外的 JSON 数据。
可预测的异常。 Moshi 在 IO 问题上抛出 IOException,在类型不匹配上抛出 JsonDataException。 Gson无处不在。
JsonReader.selectName() 避免了常见情况下不必要的 UTF-8 解码和字符串分配。
您将发布一个较小的 APK。 Gson 是 227 KiB,Moshi+Okio 加起来是 200 KiB。
Moshi 不会将平台类型的实现细节泄露到您编码的 JSON 中。这让我害怕 Gson:gson.toJson(SimpleTimeZone.getTimeZone("GMT"))
Moshi 默认不会进行奇怪的 HTML 转义。看Gson默认编码“12 & 5 = 4”为例
默认情况下未安装损坏的日期适配器。
如果您要编写新代码,我强烈建议您从 Moshi 开始。如果你有一个现有的 Gson 项目,你应该升级,如果这既简单又没有风险的话。否则坚持使用 Gson!我正在尽最大努力确保它保持兼容和可靠。
从之前的link可以看出,使用 moshi codegen 将创建编译时适配器来建模 classes,这将删除运行时反射的使用
型号
@JsonClass(generateAdapter = true)
class MyModel(val blah: Blah, val blah2: Blah)
app/build.gradle
kapt "com.squareup.moshi:moshi-kotlin-codegen:$version_moshi"
将生成带有验证的 MyModelJsonAdapter class 以确保模型属性的可空性。