OutOfMemoryError处理大型(JSON)字符串

时间:2012-09-03 13:05:35

标签: android string out-of-memory

  

可能重复:
  Out of memory error when putting large JSON (InputStream) to String

我通过HttpResponse获取编码的JSON字符串。代码如下所示:

    BasicResponseHandler brh = new BasicResponseHandler(); 
    String responseString = brh.handleResponse(response); 
    String decoded = new String(Base64.decode(responseString, Base64.NO_CLOSE));

我收到这样的错误:

09-03 12:57:09.664: E/AndroidRuntime(8309): FATAL EXCEPTION: Thread-272
09-03 12:57:09.664: E/AndroidRuntime(8309): java.lang.OutOfMemoryError
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.CharArrayBuffer.<init>(CharArrayBuffer.java:43)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.ReadWriteCharArrayBuffer.<init>(ReadWriteCharArrayBuffer.java:47)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.CharBuffer.allocate(CharBuffer.java:54)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.charset.CharsetDecoder.allocateMore(CharsetDecoder.java:236)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:195)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.nio.charset.Charset.decode(Charset.java:487)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.lang.String.<init>(String.java:174)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at java.lang.String.<init>(String.java:141)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at xxx.DataManager.doPost(DataManager.java:448)
09-03 12:57:09.664: E/AndroidRuntime(8309):     at xxx.DataManager.run(DataManager.java:185)

有时我会在

上得到它
brh.handleResponse(response); 

有时在

String decoded = new String(Base64.decode(responseString, Base64.NO_CLOSE));

所以我认为字符串太大而无法处理(我不知道如何确定它的大小以字节为单位),我该如何解决这个问题呢?

1 个答案:

答案 0 :(得分:1)

您应该切换到流式方法,其中只有最终的JSON数据结构完全保存在内存中。其他部分,特别是JSON编码的HTTP响应,由块处理块。所以他们只需要很少的内存。

这样你有几个好处:

  • 整体内存消耗大幅减少。

  • 大量分配(大型字符串)的数量大大减少。 (有时候有足够的内存可用,但没有一个足够大的部分可以分配一个大字符串。)

  • 由于解析可以在答案的第一个字节到达后立即开始,因此解析可以与数据接收并行完成。因此,应用程序变得更快。

org.json.JSONObject不支持流式传输。你将不得不改用另一个班级。

顺便说一句:我没有看到任何理由为什么Base 64编码JSON数据。 JSON是基于文本的格式,而如果二进制数据被调用则需要Base 64编码。