Android中的Moshi vs Gson [关闭]


81

我正在决定是使用Square还是Gson的Moshi来序列化和反序列化模型数据。

我一直不喜欢Gson的一件事是我认为它使用反射功能,而这在Android上可能会很慢?莫希也使用反射吗?

Moshi vs 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来提高性能。

Answers:


94

Moshi使用Okio来优化Gson不做的一些事情。

  • 读取字段名称时,Moshi不必分配字符串或进行哈希查找。
  • Moshi将输入扫描为UTF-8字节序列,然后懒惰地转换为Java字符。例如,它不需要将整数文字转换为char。

如果您已经在使用Okio流,则这些优化的优势尤其明显。RetrofitOkHttp的用户特别受益于Moshi。

关于Moshi起源的进一步讨论在我的文章Moshi,另一个JSON Processor中


它使用反射

2
@ j2emanue作为实现细节,您的自定义类的默认JsonAdapters将使用反射设置字段。
埃里克·科克伦

1
@ j2emanue可以通过使用codegen github.com/square/moshi#codegen
Pedro Lopes

34

根据swankjesse对reddit的评论

我为我在Gson上的工作感到自豪,但也对其某些局限性感到失望。我想解决这些问题,而不是“ Gson 3.0”,部分原因是我不再在Google工作。杰克(Jake),斯科特(Scott),埃里克(Eric)和我创建Moshi来解决Gson的各种局限性。这是十个比Mson胜过Gson的小理由:

  1. 即将到来的Kotlin支持。

  2. 像@HexColor int这样的限定符允许单个Java类型使用多个JSON表示形式。

  3. @ToJson和@FromJson使编写和测试自定义JSON适配器变得容易。

  4. JsonAdapter.failOnUnknown()允许您拒绝意外的JSON数据。

  5. 可预测的异常。Moshi针对IO问题抛出IOException,而针对类型不匹配抛出JsonDataException。吉森到处都是。

  6. 在通常情况下,JsonReader.selectName()避免了不必要的UTF-8解码和字符串分配。

  7. 您将发货一个较小的APK。Gson是227 KiB,Moshi + Okio一起是200 KiB。

  8. Moshi不会将平台类型的实现细节泄漏到编码的JSON中。这让我担心Gson:gson.toJson(SimpleTimeZone.getTimeZone(“ GMT”))

  9. 默认情况下,Moshi不会进行奇怪的HTML转义。以Gson的默认编码“ 12&5 = 4”为例。

  10. 默认情况下,没有安装任何损坏的日期适配器。

如果您正在编写新代码,强烈建议从Moshi开始。如果您有与Gson一起的现有项目,则应该升级,因为那将是简单且无风险的。否则,请坚持使用Gson!我正在尽力确保它保持兼容和可靠。


1

在上一个链接中,您可以看到使用moshi codegen将创建编译时适配器以建立模型类,从而消除了运行时反射的使用

模型

@JsonClass(generateAdapter = true) 
class MyModel(val blah: Blah, val blah2: Blah)

app / build.gradle

kapt "com.squareup.moshi:moshi-kotlin-codegen:$version_moshi"

将生成带有验证的MyModelJsonAdapter类,以确保模型属性的无效性。


你不认为说moshi更快吗?
j2emanue
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.