Android高性能JSON数据解析

来源:互联网 发布:ar增强现实软件 编辑:程序博客网 时间:2024/05/17 03:42

Android高性能JSON数据解析

  • 原文链接 : Hi Performance JSON Parsing in Android
  • 原文作者 : DONN FELKER
  • 译文出自 : 开发技术前线 www.devtf.cn
  • 转载声明: 本译文已授权开发者头条享有独家转载权,未经允许,不得转载!
  • 译者 : mr_dsw
  • 校对者: desmond1121
  • 状态 : 完成

有时Android开发中我们调用的1/3的API需要我们下载JSON数据。现在我有一个客户端调用一个API接口用于为设备同步数据。调用一个API返回成百上千行的JSON数据导致保存的时候形成一个8MB或者更大的JSON文件。将整个文件加载到内存中进行处理是很痛苦的,同时会导致大量内存受限的设备crash掉。然而,使用Jackson JSON数据解析类库能够一个个将http-request转换成Reader对象,Reader对象允许你处理每一个从pipe中下载下来JSON对象,它允许你从下载下来就可以处理数据而不是等到整个JSON文件加载完成。

我使用Jackson中的ObjectMapper对象反序列化JSON为POJO对象,这允许我在应用中使用domain objects,因此,我不必为任何情况下的JSON数据解析而担心或将数据存放到本地设备上(而担心)。如果你加载整个JSON文件为ObjectMapper对象,你必须创建一个很大的对象,足以占满你所有的可用内存,同时你可能会发生OutOfMemoryException异常。最终的目标是处理每一个下载的JSON对象,同时结合使用POJO的有点使用。下面是你如何使用它。

对象模型
下面我们有一个简单的customer对象需要我们下载。假想一个app拥有数以百万计的customers。每一个customer都被表示为如下的一个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}

连接API / 消费Stream
这实际上很容易,通过你的http类库(我使用http-request)连接到到你的API接口,使用HttpRequest对象的reader()方法,以便我能以此reader作为参数传递给JsonParser对象(如下所示),然后让循环建立每一个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 readerJsonParser 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添加Maven dependency在你的POM中同时关闭races。现在你可以下载巨大的JSON数据同时不必担心内存溢出。

0 0
原创粉丝点击