android中高效的JSON解析

原文地址:http://www.donnfelker.com/hi-performance-json-parsing-in-android

温馨提示:英文水平有限,仅供参考,欢迎拍砖!

在android开发中,我们有时候需要访问一个第三方的API,来请求一大块JSON格式的数据。现在,我其中的一个客户端,有一个用来向设备同步数据的API接口。一旦调用该API接口将会返回一个包含成千上万条JSON数据格式的结果。如果以JSON文件格式保存下来,则该文件大小达到8MB以上。将其完全的加载到内存中去是很痛苦的,并且在很多内存受限的设备上会造成奔溃。然而,使用Jackson这个JSON解析库,你能够使用流的方式将http-request作为一个输入流(reader)封装到Jacksons Streaming API中。该API能够让你在通信管道中有数据的时候,尽可能快的处理每一个json object对象。这使得你能够在通信管道中分段处理数据而非先把整个JSON文件加载进来。

我在Jackson中使用ObjectMapper将JSON数据转换为一个POJO类。这使得我的APP通过domain objects能够很好的工作,因此我无需担心所有地方的JSON解析操作(或者使用游标将数据移动到本地的数据库当中)。如果你需要将整个JSON文件与对象映射起来,你需要创建一个巨大无比的对象,这样很容易到达内存的边界,直到让你得到一个OutOfMemory的异常。正确的做法是,当数据来了我逐条解析JSON数据,但这也得益于使用POJO。下面是具体例子。

The ObjectModel

下面我们有一个简单的customer对象需要下载下来。想象一下,一个大型的会计类APP有着上百万的顾客。每一个顾客将会被转换为如下的POJO类。

public class Customer {
  String firstName;
  String lastName;
  // 20 Other properties

  public String getFirstName() {
    return firstName; 
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName; 
  }

  public String getLastName() {
    return lastName; 
  }

  public void setLastName(String lastName) {
    this.lastName = lastName; 
  }

  // all the other mutators and accessors

}

Connection to the API/Consuming the stream

这实际上相当简单。选择你的网络框架(我使用的是http-request),简单的访问你的API接口。使用HttpRequest的reader()方法,然后通过这个输入流转换为JsonPraser(如下),然后循环创建每一个Customer,最后我就有了每一个customer的实例。可参考注释。

// Connect to your API with your http lib, i use http-request: https://github.com/kevinsawicki/http-request
// Then get the reader. The 'request' variable below is just a HttpRequest object 
// as shown here: http://kevinsawicki.github.io/http-request/
final Reader reader = request.reader(); 

final ObjectMapper mapper = new ObjectMapper(); 
final JsonFactory factory = mapper.getFactory();

// Create a new streaming parser with the reader
JsonParser jp = factory.createParser(reader);

// I'm working with a JSON Array that is returned from the API that I'm connecting to, so I need to advance the 
// parser to the start of the array.

// Advance stream to START_ARRAY first:
jp.nextToken();

// Parse each value by looking for each start object. The Mapper will read the object and advance the parser
// until it finds the END_OBJECT at which time the mapper then deserializes into a POJO. Then the loop will 
// continue to the next position. This will handle each JSON object as it becomes available and will be very 
// light on memory and high in performance. 
while(jp.nextToken() == JsonToken.START_OBJECT) {
    // Get customer POJO
    final Customer c = mapper.readValue(jp, Customer.class);

    // Update local db with customer info.
    myDataLayer.updateCustomer(c);
}

如何使用Jackson

简单的将它作为一个库引用,或者如果你使用的是Maven,往pom文件中添加依赖。现在,你可以处理巨大的json流,而不用再担心你的内存溢出了。


想及时了解最新信息。扫一扫,添加关注微信公众号

weixin.jpg

原文地址:http://makerchen.com/2016/05/29/translate-jackson/

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 87,461评论 13 122
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 138,430评论 20 591
  • 慈溪,位于东海之滨,作为一个慈溪人,我为我家乡打call。 伴随着太阳的升起,慈溪的发展状况就尽收眼底,我为她感到...
    CCCCSJ阅读 98评论 0 0
  • 不知道什么时候起,喜欢上这个男人(理查德.克莱德曼),喜欢他所有的曲子,如痴如醉,哪怕戴上耳机听上一整天就像...
    会飞的鱼Nicole阅读 60评论 0 1
  • 北京龙泉寺,想必很多人对其都有或多或少的认识。是的,它就是那个拥有高学历高智慧僧团,与科技前段接轨,引导大众视线的...
    linsa碎碎念阅读 314评论 0 1