[HTTP那些事]超大JSON文本

Posted stay4it

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HTTP那些事]超大JSON文本相关的知识,希望对你有一定的参考价值。

扩展阅读:
[HTTP那些事] JSON数据
[HTTP那些事]JSON反序列化

在JSON反序列化一文的最后,有提到,如果有1M的JSON文本应该如何来解析?

1M的JSON String,不管用GSON,fastjson,jackson,估计都要OOM了吧。本来我想说200M的JSON数据的,想想这太坑了,就改说1M了。

答案,用JsonReader读流。比如说:

    public User readUser(JsonReader reader) throws IOException 
        String username = null;
        int followersCount = -1;

        reader.beginObject();
        while (reader.hasNext()) 
            String name = reader.nextName();
            if (name.equals("name")) 
                username = reader.nextString();
             else if (name.equals("followers_count")) 
                followersCount = reader.nextInt();
             else 
                reader.skipValue();
            
        
        reader.endObject();
        return new User(username, followersCount);
    

我去,要手写JSON解析了,这太麻烦了吧。。。
但是你想,跟性能比起来,这些体力也不算什么了吧。

上述没太多特别的地方,你可以直接看JsonReader的源码注释,里面有详细的用法示例。

在这里呢,我们先说说如何让JsonReader来读大JSON文本。

FileReader in = new FileReader(path);
JsonReader reader = new JsonReader(in);

首先,你得先把JSON文本以文件的形式存到SD卡上。再通过FileReader拿到文件流,再通过JsonReader来读流,读流的方式也就意味着是顺序读的,所以即使它不是正确的json格式,也会一直读到错误为止。

JsonReader对手写的json解析语法非常严格,写错是非常头疼的事,另外建议把nodeName变为常量去做判断,不然以后改变量名得哭瞎。

当然,Stay肯定不会讲这么简单的东西,我们怎么跟HTTP框架结合在一起呢?这解析过程肯定也是耗时操作,我总不能先用框架把数据当文件下载下来,然后再开一个线程来解析吧。这才是最蛋疼的地方。

可惜原生Volley都不支持文件下载,这里我就拿自己的HTTP框架做演示了。

简单说下实现过程:

  1. 首先写个接口,比如JsonReaderable,里面定义一个方法readFromJson(JsonReader reader)
  2. 让你想要被反序列化的对象pojo实现这个接口,比如这样
  3. 让框架先把数据当文件下载到SD卡
  4. 在callback之前再bindData,比如这样 这样就能将json数据自动反序列化成对象callback回去了。你只需要在每个对象pojo中实现readFromJson方法就好了。
  5. 如果是jsonarray怎么办,我们要返回一个ArrayList啊。比如这样
  6. 一个好的框架相当的重要啊,我们再来看外层的调用 应该不用解释吧,都能看懂。

这种情况虽然比较少见,但在一些erp啊,sap项目中经常会遇到(别问Stay怎么知道)如果你也见过android上500M的数据库,那这些心得你都能自己领悟到了。

现在我们在App中基本采取的都是分页,一般来说不需要用JsonReader,但如果Json数据超过10K以上,pojo的复杂度特别高,并且还有嵌套时,你应该考虑使用。

你也许会问,500M,即使用JsonReader读流生成对象了,内存也装不下呀。没事,你可以通过ormapping型数据库框架来存数据,比如说读200个对象存一次,清一次。或者你可以用接口回调的方式扔给外层处理,onPartialDataBinding(ArrayList list)

其实这个扩展其他第三方框架也没什么问题,只要思路有了,实现起来也就很容易了。

框架最好是根据App具体的需求以及使用场景来定制,仅会调用哪些开源lib,看不懂,改不了,这样只能让自己在技术路上越走越窄。

就写到这里,别问Stay要代码哈,只讲思维与解决方案,如果你想知道这个HTTP框架是如何从0到1的写出来的,可以看看Stay出的课程自己动手写http框架

以上是关于[HTTP那些事]超大JSON文本的主要内容,如果未能解决你的问题,请参考以下文章

json的那些事

[HTTP那些事] JSON数据

HTTP与HTTPS握手的那些事

HTTP与HTTPS握手的那些事

http 80https 443 的那些事

Http的那些事: Content-Type